SecurityContextLogoutHandler清除身份验证,即使将其设置为“ false”

时间:2018-09-04 13:46:37

标签: java spring spring-security

我目前正在尝试使用Spring Security在Spring Boot 2中为我们的应用程序实现注销机制。

我的Spring安全性注销配置为:

http
    .logout()
    .logoutRequestMatcher(new AntPathRequestMatcher("/logout.html"))
    .logoutSuccessHandler(logoutSuccessHandler)
    .addLogoutHandler(handler1)
    .addLogoutHandler(handler2)
    .clearAuthentication(false);

在这种配置下,Spring将两个处理程序以及Spring自己的LogoutFilter作为处理程序链中的最后一个处理程序添加到SecurityContextLogoutHandler中。

我们面临的问题是,在我们的自定义LogoutSuccessHandler中,我需要在安全上下文中访问存储在Authentication中的某些变量,但是上下文已在SecurityContextLogoutHandler中清除即使将.clearAuthentication(boolean clearAuthentication)设置为false

我真正不理解的是logoutSecurityContextLogoutHandler方法的实现。

public void logout(HttpServletRequest request, HttpServletResponse response,
        Authentication authentication) {
    Assert.notNull(request, "HttpServletRequest required");
    if (invalidateHttpSession) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            logger.debug("Invalidating session: " + session.getId());
            session.invalidate();
        }
    }

    if (clearAuthentication) {
        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(null);
    }

    SecurityContextHolder.clearContext();
}

即使我将clearAuthentication设置为false,也没关系,因为方法SecurityContextHolder.clearContext();的最后一行仍然会清除它。

clearAuthentication标志的意义是什么?如果需要,如何保留身份验证?

1 个答案:

答案 0 :(得分:0)

我看过源代码和文档,它基于Spring Security版本4.2.X。

SecurityContextHolder.clearContext();不会清除上下文的内容,而是将其从SecurityContextHolder的保留策略中删除。 顺便提一下,可以使用以下策略:

  • ThreadLocal
  • 可继承的ThreadLocal
  • 全球

我确定有人会指出在哪里可以阅读这些不同的策略,但这与答案无关。

  

clearAuthentication标志的意义是什么

JavaDocs这样说:“如果为true,则从SecurityContext中删除身份验证,以防止并发请求出现问题。”

也就是说,它与您在这种特定情况下尝试执行的操作几乎没有关系。

  

以及在需要时如何保留身份验证?

您实现LogoutSuccessHandler,其中Authentication对象直接传递到onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)中。 您无需执行任何其他操作即可访问该对象。