Shiro处于多线程环境中

sma*_*sma 7 java security tomcat servlets shiro

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

如果Tomcat说使用ThreadA来处理请求,那么任何调用都SecurityUtils.getSubject()应该可以正常工作.但是,一旦选择了ThreadB,用户就会丢失,getSubject返回null并且isAuthenticated现在为false.这是即使用户仍然登录.

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

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

sma*_*sma 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>
Run Code Online (Sandbox Code Playgroud)