错误页面

时间:2017-07-24 13:07:26

标签: spring-boot spring-session

根据用户是否登录,我想在错误页面上显示元素,例如

<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,则错误页面可能没有   有意义的导航。

0 个答案:

没有答案