根据用户是否登录,我想在错误页面上显示元素,例如
<div sec:authorize="isAuthenticated()">
Logged in
</div>
问题是,当前的身份验证主体由于某种原因被清除。我认为这与No Auth for You错误有关,所以我添加了
security.filter-dispatcher-types: ASYNC, FORWARD, INCLUDE, REQUEST, ERROR
然而问题仍然存在。我加载了两个项目和调试记录的弹簧安全性。通过 No Auth For You 项目,我得到了:
SecurityContextHolder now cleared, as request processing completed
Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@76d66409
Processing ErrorPage[errorCode=0, location=/error]
/error at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
/error at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImp.....
这给出了正确的安全上下文。
通过我的项目,我得到了
SecurityContextHolder now cleared, as request processing completed
Cleared thread-bound request context: org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper@380b96d
Processing ErrorPage[errorCode=0, location=/error]
/error at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
/error at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
No HttpSession currently exists
No SecurityContext was available from the HttpSession: null. A new one will be created.
所以问题似乎是&#34;目前没有HttpSession&#34;。我正在使用Redis Sessions,如果这有所作为。但是,当涉及调试时,我不知道从这里开始的确切位置。
我正在使用Spring blog中的GlobalDefaultException处理程序代码,如果这有什么不同的话。但是我实际上将这个处理程序移植到 No Auth For You 项目中,所以我不相信它。
如果我离开此错误页面并查看任何其他页面,那么我仍然会登录。
更新
我删除了Redis,它可以找到会话。也许这与Tomcat和Redis有关?
更新2018年
我再次看过这个,我认为它与GlobalExceptionHandler有关(如前面提到的那样,来自Spring的博客)。
&#34;如果你想拥有任何异常的默认处理程序,那就会有轻微的皱纹。您需要确保框架处理带注释的异常。&#34;
@ControllerAdvice
public class GlobalExceptionHandler
{
@ExceptionHandler({Exception.class})
@ResponseStatus(value = INTERNAL_SERVER_ERROR)
public String exception(
HttpServletRequest request,
Exception e,
Model model
) throws Exception
{
// other logging things here
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
{
// template that renders this can't access the SecurityContext
throw e;
}
// this template can access the SecurityContext
return "error";
}
}
捕获的异常能够访问SecurityContext,但是重新抛出的异常(由Spring处理)无法访问SecurityContext。
请记住,当没有使用Redis时,两个模板都可以访问SecurityContext。我看了documentation for Spring Session,然后说
&#34; ... [t]他创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。过滤器负责替换Spring会话支持的HttpSession实现。&#34;
所以也许这个豆子因某种原因没被使用?
在Spring Boot 2.0.0.M7下它可以工作,所以我想知道改变了什么
DEBUG 3767 --- [0.1-8080-exec-1] o.s.security.web.FilterChainProxy : /errorTest/notFound at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG 3767 --- [0.1-8080-exec-1] o.s.d.redis.core.RedisConnectionUtils : Opening RedisConnection
DEBUG 3767 --- [0.1-8080-exec-1] io.lettuce.core.RedisChannelHandler : dispatching command AsyncCommand [type=HGETALL, output=MapOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]
[SNIP REDIS]
DEBUG 3767 --- [0.1-8080-exec-1] o.s.d.redis.core.RedisConnectionUtils : Closing Redis Connection
DEBUG 3767 --- [0.1-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@936f4f11: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken
我认为这与以下问题有关: https://github.com/spring-projects/spring-boot/issues/5737
我认为默认情况下更改SecurityFilterAutoConfiguration以使用ERROR调度类型是有意义的。 ERROR调度类型也是Spring Security的Servlet Java配置的默认值。
ERROR调度类型对Spring Security有意义的原因很多时候导航是基于当前用户的权限。如果没有填充Spring Security,则错误页面可能没有 有意义的导航。