【问题标题】:Spring security - Get SESSION cookie value in AuthenticationSuccessHandlerSpring security - 在 AuthenticationSuccessHandler 中获取 SESSION cookie 值
【发布时间】:2019-06-24 23:25:16
【问题描述】:

我知道 Spring Security 在成功验证时会创建一个名为 SESSION 的 cookie。是否可以在 AuthenticationSuccessHandler 中获取该 cookie 值。

我有以下实现,其中我需要 SESSION cookie 值。我看起来是 HttpServletResponse 的响应标头,但它们有 XSRF-TOKEN 设置 cookie 标头,

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

  @Override
  public void onAuthenticationSuccess(
      HttpServletRequest request, HttpServletResponse response, Authentication authentication)
      throws IOException {

   // GET SESSION, COOKIE VALUE HERE
  }
}

你能帮忙吗?

【问题讨论】:

  • HttpServletResponse的set-cookie header的值是多少?是{'Set-Cookie': 'SESSION=xxxx-xxxx-xxxx-xxxxxxx;的形式吗?路径=/; HttpOnly'} ?

标签: spring spring-boot spring-security spring-session


【解决方案1】:

SESSION cookie 是由 Spring Session 的DefaultCookieSerializer 创建的,每次创建新的 Session 时都会调用,不一定要在认证成功后。

Spring Session 的SessionRepositoryFilter 以这样一种方式包装 HttpServletRequest,即每当您在应用程序中的任何位置从请求中获取 HttpSession 时,您实际上都获得了 Spring Session 对象。然而,这个 cookie 会在你的处理程序被调用后写入响应,正如你在 SessionRepositoryFilter 中看到的那样:

try {
        filterChain.doFilter(wrappedRequest, wrappedResponse);
    }
    finally {
        wrappedRequest.commitSession(); //the SESSION cookie is created if necessary
    }

因此,如果刚刚为此请求创建了会话...

  1. 该 cookie 在 HttpServletRequest 中不可用,因为该 cookie 尚未发送(因此浏览器无法发送它)
  2. cookie 不会将 HttpServletResponse 作为“Set-Cookie”标头,因为它将在您的应用程序处理请求后写入。

但是,您可以获得 cookie 值:

String cookieValue = request.getSession().getId();

注意:上面的代码将强制 Spring Session 创建一个会话支持的 Redis/Jdbc/etc,稍后将用于生成 SESSION cookie。

【讨论】:

    【解决方案2】:

    我使用请求中的getSession().getId() 方法得到它。我的示例是在 Kotlin 中使用 Webflux 实现,但显然在 HttpServletRequest 实现中的工作方式类似,请参阅 https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpServletRequest.html#getSession--

    class AuthenticationSuccessHandler : ServerAuthenticationSuccessHandler {
      private val location = URI.create("https://redirect.page")
      private val redirectStrategy: ServerRedirectStrategy = DefaultServerRedirectStrategy()
    
      override fun onAuthenticationSuccess(webFilterExchange: WebFilterExchange?, authentication: Authentication?): Mono<Void> {
        val exchange = webFilterExchange!!.exchange
        return exchange.session.flatMap {
          it.id // 87b5639c-7404-48a1-b9da-3ca47691a962
          this.redirectStrategy.sendRedirect(exchange, location)
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-17
      • 2014-01-04
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 2011-11-20
      • 1970-01-01
      • 2015-11-18
      相关资源
      最近更新 更多