2012-03-22 145 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