java - SecurityContextLogoutHandler 清除身份验证,即使设置为 'false'

标签 java spring spring-security

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

我的 spring security 注销配置是:

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

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

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

我真正不明白的是SecurityContextLogoutHandlerlogout方法的实现。

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 标志有什么意义?如果需要,如何保留身份验证?

最佳答案

我看过源代码和文档,这是基于 Spring Security 4.2.X 版的。

SecurityContextHolder.clearContext(); 不会清除上下文的内容,而是将其从 SecurityContextHolder 的持有策略中移除。 另外,可以使用以下策略:

  • 本地线程
  • 可继承的ThreadLocal
  • 全局

我相信有人会指出在哪里可以阅读这些不同的策略,但这与这个答案并不相关。

What is the point of the clearAuthentication flag

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

也就是说,它与您在此特定情况下尝试做的事情几乎没有关系。

and how to retain the Authentication if I need to?

您实现 LogoutSuccessHandler其中 Authentication 对象直接传递到 onLogoutSuccess(HttpServletRequest 请求,HttpServletResponse 响应,Authentication 身份验证)。 您无需执行任何其他操作即可访问该对象。

关于java - SecurityContextLogoutHandler 清除身份验证,即使设置为 'false',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52167825/

相关文章:

spring-boot - 无法使用 KeycloakAutoConfiguration 使用 Spring Boot Security UnsatisfiedDependencyException 设置 Keycloak

java - spring jsp <%%> 在页面上可见

java - sql 文件中的 ScriptStatementFailedException

java - 带有嵌入式 Tomcat 的 Spring Boot 会忽略方法角色

spring - 使用类路径 : in spring

spring - 对于使用过 Spring 框架的人来说,哪个 PHP 框架会更容易使用?

java - Spring boot Security,Oauth2 注销,使 session 无效,以便在授权服务器中完成身份验证和批准周期

java - 自定义 ListAdapter 的 Hashmap 中出现空指针异常?

java - 从 InputStream 解析日期时出现 ParseException

java - 如何避免 arraylist 的嵌套 for 循环,java