我理解Shiro的SecurityUtils.getSubject()
工作的基本方法是返回绑定到当前正在执行的线程的主题。但是,这似乎与像Tomcat这样使用线程池为请求提供服务的servlet容器不一致。
如果Tomcat说使用ThreadA来处理请求,那么对SecurityUtils.getSubject()
的任何调用都应该可以正常工作。但是,一旦选择了ThreadB,用户就会丢失,getSubject
返回null并且isAuthenticated现在为false。这是即使用户仍然登录。
我已在我的申请中证实了这一点。我正在使用Shiro Core 1.2,并注意到当我浏览我的应用程序时,我的用户只是奇迹般地未经验证。如果我查看日志,只要使用不同的线程来处理请求,问题就会发生。
那么,我是否错误地配置了Shiro?似乎'当前用户'应该被绑定到比当前线程更持久的东西。我希望它是基于会话的。我知道Shiro有会话管理,但在我发现的所有示例中,它都说通过调用getSubject
来查看当前用户,它查看了ThreadContext。我错过了什么吗?
答案 0 :(得分:13)
所以,事实证明我没有正确配置Shiro。我有一个Web应用程序,但我在代码中设置了安全管理器。这导致安全管理器仅在某个线程上设置。只要请求由同一个线程提供服务,它就可以正常工作。但是一旦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>