Apache Shiro和Google Guice:将依赖注入Realm

4 java dependency-injection jersey guice shiro

我与Jersey开发了一个rest api,并希望使用Google Guice for Dependency Injection和Apache Shiro作为安全框架.

对于身份验证,我创建了一个自定义域,我必须注入一个连接到EntityManager的自定义身份验证器.

但是依赖关系不会注入到Realm中.我想shiro.ini(我必须定义使用的领域)不是由guice管理的.

如何将依赖项注入Apache Shiro,尤其是使用的Realm?

我的web.xml只有一个映射到guice的过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>GuiceServletConfig</listener-class>
</listener>
</web-app>
Run Code Online (Sandbox Code Playgroud)

我的GuiceServletConfig配置所有依赖项,包括CustomRealm

public class GuiceServletConfig extends GuiceServletContextListener {

@Override
protected Injector getInjector() {
    return Guice.createInjector(new DbModule(), new JerseyServletModule() {

        @Override
        protected void configureServlets() {
            // ...
            // CustomRealm is only used when i use it as an eager singleton
            bind(CustomRealm.class).asEagerSingleton();
            bind(org.apache.shiro.web.servlet.IniShiroFilter.class).in(Singleton.class);
            filter("/*").through(org.apache.shiro.web.servlet.IniShiroFilter.class);
            serve("/api/*").with(GuiceContainer.class);
        }
    });
}
}
Run Code Online (Sandbox Code Playgroud)

shiro ini只定义了领域

[main]
myRealm = CustomRealm
[users] # for testing
root = secret,admin
[roles] # for testing
admin = *
[urls]
/api/** = authcBasic
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 5

Apache Shiro的INI配置适用于许多用例,但如果您拥有像Spring或Guice这样的IoC框架的全部功能,通常最好直接在IoC机制中配置所有Shiro.Shiro的Spring集成就是一个很好的例子:http://shiro.apache.org/spring.html 建议在Guice环境中做几乎相同的事情.

如果你不想这样做而宁愿留在INI,那么Shiro有一个RealmFactory概念.

您可以创建一个与Guice环境通信的RealmFactory实现,并"拉取"您的Guice配置的域.然后在Shiro INI中定义RealmFactory实现:

[main]
...
guiceRealmFactory = com.foo.bar.shiro.GuiceRealmFactory
...
Run Code Online (Sandbox Code Playgroud)

但请注意,Shiro的INI仅支持通过RealmFactory从INI外部获取Realm实例 - 所有其他引用的对象必须在INI中定义.您可能想要打开一个Shiro Jira问题,要求提供更广泛的工厂支持,而不仅仅是领域.

最终,因为Guice比INI更强大,所以如果可能的话,建议在Guiro中配置Shiro中的所有内容(SecurityManager,领域,ShiroFilter等)