Apache Shiro 集成-Guice

来源:互联网 发布:兰新高铁 知乎 编辑:程序博客网 时间:2024/05/29 03:03

Shiro集成Guice是在1.2版本里新增的功能。

Shiro提供了三个Guice模块可包含到你的应用系统:

l ShiroModule

为配置SecurityManager, any Realms和其他的Shiro组件提供最基本的集成。

通过扩展此模块来增加你自定义的配置。

l ShiroWebModule

此模块扩展了ShiroModule模块,用来设置web环境和配置过滤器链。使用GuiceServlet Module来配置这些过滤器,需要在被设置。

与ShiroModule 模块一样,可以通过扩展来增加自定义的配置。

l ShiroAOPModule

使用Guice AOP来实现Shiro AOP的注解。这个模块主要实现了Shiro AnnotationMethodInterceptors来遵循Guice的方法拦截器模式。

你也可以非常容易地注册你自己写的AnnotationMethodInterceptors。

一个非常简单的自定义Realm示例如下:在这个列子里userrole的配置都在shiro.ini文件里。

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");

    }

}

然后创建一个Guice注射器,这个注射器被用来获取SecurityManager。

Injector injector = Guice.createInjector(new MyShiroModule());

SecurityManager securityManager = injector.getInstance(SecurityManager.class);

SecurityUtils.setSecurityManager(securityManager);

Shiro包含几个注解和方法拦截器通过AOP来执行授权。它还提供一个简单的API来编写Shiro特定的方法拦截器,shiro-guice支持ShiroAOPModule。要使用它,只需实例化并且安装这个模块到你的应用中。

Injector injector = Guice.createInjector(new MyShiroModule(), new ShiroAopModule(), new MyApplicationModule());

你可以扩展ShiroAopModule来编写你自己的拦截器:

class MyShiroAopModule extends ShiroAopModule {

    protected void configureInterceptors(AnnotationResolver resolver)

    {

        bindShiroInterceptor(new MyCustomAnnotationMethodInterceptor(resolver));

    }

}

Shiro-guiceweb集成设计成将Shiro及它的过滤器范例与Guiceservlet Module的整合。如果你在一个web环境下使用ShiroGuice’s servlet Module,那么你应该扩展ShiroWebModule而不是ShiroModule。你的web.xml应当和Guice’s servlet Module建议的一样。

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");

    }

}

在上面的代码中我们建立了一个IniRealm和4个过滤器,在ini文件中配置如下:

[urls]

    /public/** = anon

    /stuff/allowed/** = authcBasic, perms["yes"]

    /stuff/forbidden/** = authcBasic, perms["no"]

    /** = authcBasic

shiro-guice中过滤器的名字是Guice的主键。所有Shiro自带的过滤器都定义为常量,你也可以自己定义过滤器:

Key customFilter = Key.get(MyCustomFilter.class);

addFilterChain("/custom/**", customFilter);

我们不得不告诉shiro-guice我们自定义的Shiro过滤器。由于ShiroWebModule是私有的,guice-servlets没有提供解析过滤器映射的方法,所以我们必须手动地将其绑定:

ShiroWebModule.guiceFilterModule()

ShiroWebModule.bindGuiceFilter(binder())

通过setter方法可以设置很多的Shiro配置参数,shiro-guice将注入这些配置参数通过查找约束符@Named("shiro.{propName}")。例如,要设置会话超时,您可以执行以下操作。

bindConstant().annotatedWith(Names.named("shiro.globalSessionTimeout")).to(30000L);

Shiro-guice使用TypeListener去注入本地的Shiro类(任何org.apache.shiro目录下的类而不是org.apache.shiro.guice)。然而Guice只显式地绑定TypeListeners类型的,如果你想要注入一个Shiro对象你必须显式地声明它。例如,如果想为一个realm设置CredentialsMatcher,需要添加以下的绑定:

bind(CredentialsMatcher.class).to(HashedCredentialsMatcher.class);

bind(HashedCredentialsMatcher.class);

bindConstant().annotatedWith(Names.named("shiro.hashAlgorithmName")).to(Md5Hash.ALGORITHM_NAME);

原创粉丝点击