2011-06-10 117 views
7

我正在嘗試爲403(拒絕訪問)和500(內部服務器錯誤)之類的錯誤編寫自定義錯誤頁面。它們將從Velocity模板呈現,並使用用戶的語言環境翻譯所有消息。身份驗證和區域設置解析在應用程序中正常工作。Spring SecurityContext在錯誤頁面返回空身份驗證

我將web.xml中的位置設置爲所需的頁面,並在webmvc-context.xml中添加了通過請求到視圖的控制器。

我碰到的問題是SecurityContextHolder.getContext()。getAuthentication()在錯誤頁面視圖中返回null。看着我看到日誌:

06.10 14:42:26 DEBUG - context.HttpSessionSecurityContextRepository(HttpSessionSecurityContextRepository.java:351) - - SecurityContext stored to HttpSession: '[email protected]e7b0b7: Authentication: ... 
06.10 14:42:26 DEBUG - context.SecurityContextPersistenceFilter(SecurityContextPersistenceFilter.java:89) - - SecurityContextHolder now cleared, as request processing completed 
06.10 14:42:26 DEBUG - servlet.DispatcherServlet(DispatcherServlet.java:691) - - DispatcherServlet with name 'foo' processing GET request for [/foo/app/error/403.html] 

因此,無論春季或Tomcat重定向到一個錯誤頁面,並最終確定了請求武功,因此上下文被清除。而新的「請求」不經歷Spring Security過濾器,因此不會恢復上下文。

通常的方法是不行的,但似乎驗證信息是在會議的地方,也因爲AbstractTemplateView記錄以下:

Exposing session attribute 'SPRING_SECURITY_CONTEXT' with value [[email protected]fbd958: Authentication: org.springframework.security[email protected]edfbd958... 

如何正確獲取,使正常和錯誤頁面將採取相同的行動?

回答

5

你正在運行到的問題是,它轉換成例外的錯誤頁面的ExceptionTranslationFilter來自哪個拉認證在SecurityContextRepository,並把它放入SecurityContextHolderSecurityContextPersistenceFilter之前。當請求結束時,SecurityContextPersistenceFilter將信息從SecurityContextHolder中取出。

它清除SecurityContextHolder的原因是SecurityContextHolder通常是線程本地的,如果servlet容器要重用線程(大多數情況下是這樣做的),他們可能會意外地將這些憑據提供給其他人。

通常ExceptionTranslationFilter是最外層的過濾器,用於避免任何異常無法翻譯的風險。

你最好的選擇是可能會寫一個自定義ExceptionTranslationFilter這需要在SecurityContextRepository(通常是HTTP,你提到的會議),並提供通過SecurityContextRepository而不是SecurityContextHolder訪問Authentication。請記住,如果用戶未登錄,Authentication仍然爲空。

+0

謝謝!我接受了你的答案,因爲它給了我正確的輸入:'ExceptionTranslationFilter'是處理異常的人。它具有'accessDeniedHandler'屬性,默認情況下是'AccessDeniedHandlerImpl'的一個實例。幸運的是它有一個'errorPage'屬性,文檔指出,「作爲」向前「,'SecurityContextHolder'將保持填充狀態。」我重新連接了我的豆子,它工作了! – Infeligo 2011-06-13 07:19:00

5

問題可能在於springSecurityFilterChain不攔截ERRORS。嘗試在web.xml中更改映射爲

<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>ERROR</dispatcher> 
</filter-mapping> 
+0

這讓它爲我工作錯誤頁面現在知道你是否登錄或不 – 2015-10-06 08:13:21