2012-03-22 1047 views
6

我理解Shiro的SecurityUtils.getSubject()的基本方法是它返回绑定到当前正在执行的线程的主题。但是,这似乎与Tomcat等使用线程池来处理请求的servlet容器不一致。Shiro在多线程环境中

如果Tomcat使用ThreadA来处理请求,则任何对SecurityUtils.getSubject()的调用都应该正常工作。但是,只要选择了ThreadB,用户就会丢失,getSubject返回null,isAuthenticated现在为false。这是即使用户仍然登录。

我已经在我的应用程序中确认了这一点。我正在使用Shiro Core 1.2,并注意到当我浏览我的应用程序时,我的用户只是奇迹般地未经认证。如果我查看日志,只要使用不同的线程来处理请求,就会发生问题。

那么,我有Shiro配置不正确吗?看起来'当前用户'应该被绑定到比当前线程更持久一些的东西。我希望它是基于会话的。我知道Shiro有会话管理,但在我发现的所有示例中,它都表示通过调用getSubject来获取当前用户,该用户查看ThreadContext。我错过了什么吗?

回答

12

所以,事实证明,我只是没有正确配置Shiro。我有一个网络应用程序,但我在代码中设置安全管理器。这导致安全管理器仅在特定线程上建立。只要请求由同一个线程提供服务,它就可以正常工作。但是,只要Tomcat选择了不同的线程,用户就显得无法认证了。

Shiro有一个Web应用程序的过滤器来处理这种情况,并将用户绑定到每个传入的请求。您应该配置您的应用程序,如下所示,而不是在代码中执行安全管理器:

<context-param> 
    <param-name>shiroConfigLocations</param-name> 
    <param-value>classpath:auth.ini</param-value> 
</context-param> 

<!-- Shiro Environment Listener --> 
<listener> 
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> 
</listener> 

<!-- Shiro Filter Configuration --> 
<filter> 
    <filter-name>ShiroFilter</filter-name> 
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>ShiroFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
+0

感谢您报告这个写得很好的响应sma! – 2012-03-25 09:54:29

+0

我对'SecurityUtils.getSubject()'有一些疑问。由于tomcat容器中有一个线程池,因此一个线程可能绑定到多个主题? – znlyj 2015-11-22 00:19:08