2011-06-10 81 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