| <a name="Guice-IntegratingApacheShirointoGuicebasedApplication"></a> |
| Integrating Apache Shiro into Guice based Application |
| ===================================================== |
| |
| Shiro [Guice](https://github.com/google/guice) integration was added in Shiro 1.2\. This page covers the ways to integrate Shiro into Guice-based applications using standard Guice conventions and mechanisms. Prior to reading this integration document, you should be a least somewhat familiar with Guice. |
| |
| <a name="Guice-Overview"></a> |
| Overview |
| -------- |
| |
| shiro-guice provides three Guice modules that can be included in your application. |
| |
| * ShiroModule |
| * Provides basic integration for setting up the `SecurityManager`, any `Realms`, and any other Shiro configuration. |
| * This module is used by extending it and adding your own custom configuration. |
| |
| * ShiroWebModule |
| * Extension of `ShiroModule` that sets up the web environment and also allows for filter chain configuration. This uses the [Guice Servlet Module](https://github.com/google/guice/wiki/ServletModule) to configure the filters, and so requires that to be setup. |
| * Like the `ShiroModule`, this module is used by extending it and adding your own custom configuration. |
| |
| * ShiroAopModule |
| * Uses [Guice AOP](https://github.com/google/guice/wiki/AOP) to implement the Shiro AOP annotations. This module is primarily concerned with adapting Shiro `AnnotationMethodInterceptors` to the Guice method interceptor model. |
| * This module is typically used by simply installing it. However, if you have your own `AnnotationMethodInterceptors` written for Shiro, they can be easily incorporated by extending it. |
| |
| <a name="Guice-GettingStarted"></a> |
| Getting Started |
| --------------- |
| |
| The most simple configuration is to extend `ShiroModule` to install your own `Realm`. |
| |
| ``` java |
| class MyShiroModule extends ShiroModule { |
| protected void configureShiro() { |
| try { |
| bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class)); |
| } catch (NoSuchMethodException e) { |
| addError(e); |
| } |
| } |
| |
| @Provides |
| Ini loadShiroIni() { |
| return Ini.fromResourcePath("classpath:shiro.ini"); |
| } |
| } |
| ``` |
| |
| In this case, user and role configuration would go in the `shiro.ini` file. |
| |
| #warning('shiro.ini usage in Guice', 'It is important to note that, in this above configuration, only the `users` and `roles` sections from the ini file are used.') |
| |
| Then, the module is used to create a Guice injector, and the injector is used to obtain a `SecurityManager`. The following example serves the same purpose as the first three lines in the [Quickstart](10-minute-tutorial.html#10MinuteTutorial-Quickstart.java) example. |
| |
| ``` java |
| Injector injector = Guice.createInjector(new MyShiroModule()); |
| SecurityManager securityManager = injector.getInstance(SecurityManager.class); |
| SecurityUtils.setSecurityManager(securityManager); |
| ``` |
| |
| <a name="Guice-AOP"></a> |
| AOP |
| --- |
| |
| Shiro includes several annotations and method interceptors useful for performing authorization via AOP. It also provides a simple API for writing Shiro-specific method interceptors. shiro-guice supports this with the `ShiroAopModule`. |
| |
| To use it, simply instantiate and install the module alongside your application module and your `ShiroModule`. |
| |
| ``` java |
| Injector injector = Guice.createInjector(new MyShiroModule(), new ShiroAopModule(), new MyApplicationModule()); |
| ``` |
| |
| If you have written custom interceptors that conform to Shiro's api, you may find it useful to extend the `ShiroAopModule`. |
| |
| ``` java |
| class MyShiroAopModule extends ShiroAopModule { |
| protected void configureInterceptors(AnnotationResolver resolver) |
| { |
| bindShiroInterceptor(new MyCustomAnnotationMethodInterceptor(resolver)); |
| } |
| } |
| ``` |
| |
| <a name="Guice-Web"></a> |
| Web |
| --- |
| |
| shiro-guice's web integration is designed to integrate Shiro and its filter paradigm with Guice's servlet module. If you are using Shiro in a web environment, and using Guice's servlet module, then you should extend ShiroWebModule rather than ShiroModule. Your web.xml should be setup exactly as Guice's servlet module recommends. |
| |
| ``` java |
| class MyShiroWebModule extends ShiroWebModule { |
| MyShiroWebModule(ServletContext sc) { |
| super(sc); |
| } |
| |
| protected void configureShiroWeb() { |
| try { |
| bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class)); |
| } catch (NoSuchMethodException e) { |
| addError(e); |
| } |
| |
| addFilterChain("/public/**", ANON); |
| addFilterChain("/stuff/allowed/**", AUTHC_BASIC, config(PERMS, "yes")); |
| addFilterChain("/stuff/forbidden/**", AUTHC_BASIC, config(PERMS, "no")); |
| addFilterChain("/**", AUTHC_BASIC); |
| } |
| |
| @Provides |
| Ini loadShiroIni() { |
| return Ini.fromResourcePath("classpath:shiro.ini"); |
| } |
| } |
| ``` |
| |
| In the previous code, we have bound an `IniRealm` and setup four filter chains. These chains would be equivalent to the following ini configuration. |
| |
| ``` ini |
| [urls] |
| /public/** = anon |
| /stuff/allowed/** = authcBasic, perms["yes"] |
| /stuff/forbidden/** = authcBasic, perms["no"] |
| /** = authcBasic |
| ``` |
| |
| In shiro-guice, the filter names are Guice keys. All of the default Shiro filters are available as constants, but you are not limited to those. In order to use a custom filter in a filter chain, you would do |
| |
| ``` java |
| Key customFilter = Key.get(MyCustomFilter.class); |
| |
| addFilterChain("/custom/**", customFilter); |
| ``` |
| |
| We still have to tell guice-servlets about our Shiro filter. Since the `ShiroWebModule` is private, and guice-servlets does not give us a way to expose a filter mapping, we have to bind it manually. |
| |
| ``` java |
| ShiroWebModule.guiceFilterModule() |
| ``` |
| |
| Or, from within an application module, |
| |
| ``` java |
| ShiroWebModule.bindGuiceFilter(binder()) |
| ``` |
| |
| <a name="Guice-Properties"></a> |
| Properties |
| ---------- |
| |
| A number of Shiro classes expose configuration parameters via setter methods. shiro-guice will inject these if it finds a binding for `@Named("shiro.{propName}")`. For instance, to set the session timeout, you could do the following. |
| |
| ``` java |
| bindConstant().annotatedWith(Names.named("shiro.globalSessionTimeout")).to(30000L); |
| ``` |
| |
| If this paradigm doesn't work for you, you may also consider using a provider to instantiate the object and invoking the setters directly. |
| |
| <a name="Guice-InjectionofShiroObjects"></a> |
| Injection of Shiro Objects |
| -------------------------- |
| |
| shiro-guice uses a Guice `TypeListener` to perform injection on native Shiro classes (any class in a subdirectory of `org.apache.shiro` but not `org.apache.shiro.guice`). However, Guice only considers explicitly bound types as candidates for `TypeListeners`, so if you have a Shiro object that you want injected, you have to declare it explicitly. For instance, to set the `CredentialsMatcher` for a realm, we would need to add the following bindings: |
| |
| ``` java |
| bind(CredentialsMatcher.class).to(HashedCredentialsMatcher.class); |
| bind(HashedCredentialsMatcher.class); |
| bindConstant().annotatedWith(Names.named("shiro.hashAlgorithmName")).to(Md5Hash.ALGORITHM_NAME); |
| ``` |
| |
| #lendAHandDoc() |
| |
| <input type="hidden" id="ghEditPage" value="guice.md.vtl"></input> |