多线程环境中的 Shiro

Posted

技术标签:

【中文标题】多线程环境中的 Shiro【英文标题】:Shiro in a multi-threaded environment 【发布时间】:2012-04-07 10:46:58 【问题描述】:

我理解 Shiro 的SecurityUtils.getSubject() 工作的基本方式是它返回绑定到当前执行线程的主题。然而,这似乎与 Tomcat 等使用线程池来服务请求的 servlet 容器不一致。

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

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

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

【问题讨论】:

【参考方案1】:

所以,事实证明我只是没有正确配置 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>

【讨论】:

感谢您用这个写得很好的回复 sma 进行报告! 我对@9​​87654322@ 有一些疑问。由于tomcat容器中有线程池,一个线程可能绑定到多个主体?

以上是关于多线程环境中的 Shiro的主要内容,如果未能解决你的问题,请参考以下文章

多线程环境中的 PetaPoco 事务

C++ 多线程环境中的内存访问

多线程编程之Linux环境下的多线程

多线程环境中的字节缓冲区[重复]

多线程编程之Linux环境下的多线程

多线程环境中的事件