将 Apache Shiro 集成到基于 Guice 的应用程序中

在 Shiro 1.2 中添加了 Shiro Guice集成。该页面介绍了使用标准 Guice 约定和机制将 Shiro 集成到基于 Guice 的应用程序中的方法。在阅读此集成文档之前,您应该至少对 Guice 有所了解。

Overview

shiro-guice 提供了三个可以包含在您的应用程序中的 Guice 模块。

  • ShiroModule

  • 提供基本的集成,以设置SecurityManager,任何Realms以及任何其他 Shiro 配置。

    • 通过扩展该模块并添加您自己的自定义配置来使用此模块。
  • ShiroWebModule

  • extensionsShiroModule可以设置网络环境,还可以配置过滤器链。这使用Guice Servlet 模块来配置过滤器,因此需要对其进行设置。

    • ShiroModule一样,可以通过扩展该模块并添加自己的自定义配置来使用该模块。
  • ShiroAopModule

  • 使用Guice AOP来实现 Shiro AOPComments。该模块主要涉及使 Shiro AnnotationMethodInterceptors适应 Guice 方法拦截器模型。

    • 通常只需安装即可使用此模块。但是,如果您为 Shiro 编写了自己的AnnotationMethodInterceptors,则可以通过扩展将它们轻松合并。

Getting Started

最简单的配置是扩展ShiroModule以安装自己的Realm

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

在这种情况下,用户和角色配置将放在shiro.ini文件中。

shiro.ini usage in Guice

重要的是要注意,在上述配置中,仅使用了 ini 文件中的“ users”和“ roles”部分。

然后,该模块用于创建 Guice 注射器,并且该注射器用于获得SecurityManager。以下示例与Quickstart示例中的前三行具有相同的目的。

Injector injector = Guice.createInjector(new MyShiroModule());
SecurityManager securityManager = injector.getInstance(SecurityManager.class);
SecurityUtils.setSecurityManager(securityManager);

AOP

Shiro 包含一些注解和方法拦截器,可用于通过 AOP 执行授权。它还提供了用于编写 Shiro 特定方法拦截器的简单 API。 shiro-guice 使用ShiroAopModule支持此功能。

要使用它,只需实例化该模块并将其与您的应用程序模块和ShiroModule一起安装。

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

如果您编写了符合 Shiro api 的自定义拦截器,则可能会发现扩展ShiroAopModule很有用。

class MyShiroAopModule extends ShiroAopModule {
    protected void configureInterceptors(AnnotationResolver resolver)
    {
        bindShiroInterceptor(new MyCustomAnnotationMethodInterceptor(resolver));
    }
}

Web

shiro-guice 的 Web 集成旨在将 Shiro 及其过滤器范例与 Guice 的 servlet 模块集成。如果在 Web 环境中使用 Shiro,并使用 Guice 的 servlet 模块,则应扩展 ShiroWebModule 而不是 ShiroModule。您的 web.xml 应该完全按照 Guice 的 servlet 模块推荐的设置。

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并设置了四个过滤器链。这些链等效于以下 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);

我们仍然必须告诉 guice-servlets 我们的 Shiro 过滤器。由于ShiroWebModule是私有的,并且 guice-servlet 没有提供公开过滤器 Map 的方法,因此我们必须手动绑定它。

ShiroWebModule.guiceFilterModule()

或者,在应用程序模块中,

ShiroWebModule.bindGuiceFilter(binder())

Properties

许多 Shiro 类通过 setter 方法公开配置参数。如果 shiro-guice 找到@Named("shiro.{propName}")的绑定,它们将注入它们。例如,要设置会话超时,您可以执行以下操作。

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

如果此范例对您不起作用,您还可以考虑使用提供程序来实例化对象并直接调用设置器。

注入 Shiro 对象

shiro-guice 使用 Guice TypeListener对本地 Shiro 类(org.apache.shiro子目录中的任何类,但不是org.apache.shiro.guice的子类)进行注入。但是,Guice 仅将显式绑定类型视为TypeListeners的候选对象,因此,如果您有要注入的 Shiro 对象,则必须显式声明它。例如,要为领域设置CredentialsMatcher,我们需要添加以下绑定:

bind(CredentialsMatcher.class).to(HashedCredentialsMatcher.class);
bind(HashedCredentialsMatcher.class);
bindConstant().annotatedWith(Names.named("shiro.hashAlgorithmName")).to(Md5Hash.ALGORITHM_NAME);

协助处理文档

尽管我们希望该文档对您使用 Apache Shiro 所做的工作有所帮助,但社区一直在不断改进和扩展文档。如果您想为 Shiro 项目提供帮助,请考虑在需要的地方更正,扩展或添加文档。您提供的每一点帮助都会扩大社区,进而改善 Shiro。

提交文档的最简单方法是通过单击下面的Edit链接提交请求请求,然后将其发送到User Forum用户邮件列表