CSRF过滤器顺序和随机令牌生成。

问题描述 投票:0回答:1

我在生成XSRF令牌和更新必要的cookie值方面遇到了一些奇怪的行为。 当我加载网站的登陆页面时--一个Angular前端和一个Spring-boot后端--会生成XSRF标记。 不是,理想的,但如果这是正常的和预期的,那么我可以接受。 在进入登陆页面时,唯一产生的请求是 "GET "请求。

在我登录到应用程序后,它验证了第一个XSRF-TOKEN并验证其有效性,然后继续登录。 然而,紧接着又生成了一个新的CSRF token,改变了Web服务上的XSRF-TOKEN。 因此,现在前端和后端是不同步的。 我不知道如何在成功登录后更新XSRF-TOKEN,或者防止它被更改,因为这样做似乎没有任何好处......至少从我读到的资料来看是这样。

网络安全

@Override
protected void configure(HttpSecurity http) throws Exception {
    CsrfHeaderFilter csrfHeaderFilter = new CsrfHeaderFilter();

    http.httpBasic()
        .authenticationEntryPoint(new AuthenticationFailureHandler())
        .and()
            .authorizeRequests()
            .antMatchers("List of API URI").permitAll()
            .anyRequest().authenticated();

    // Configurations for CSRF end points
    http.httpBasic()
        .authenticationEntryPoint(new AuthenticationFailureHandler())
        .and()
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
        .and()
            .authorizeRequests()
            .antMatchers("Login API URI").permitAll()
        .and()
            .addFilterAfter(csrfHeaderFilter, CsrfFilter.class);

        // Logout configurations
        http.logout()
        .permitAll()
        .logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}

csrf部分是分开的,希望csrf令牌只有在发送了URI的post请求时才会生成。 但事实似乎并非如此。 似乎CSRF头过滤器会被调用,而不管发送到后台的是什么URI。

CSRF头过滤器 -- 需要,因为必须更新cookie的域,以允许前端和后端访问XSRF-TOKEN。

@Override
protected void doFilterInternal(HttpServletRequest request,
                                  HttpServletResponse response, FilterChain filterChain)
          throws ServletException, IOException {

    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
            .getName());

    if (csrf != null) {
      Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
      String token = csrf.getToken();
      if (cookie == null || (token != null && !token.equals(cookie.getValue()))) {
        cookie = new Cookie("XSRF-TOKEN", token);
        cookie.setPath("/");
        cookie.setDomain(<omitted>);
        response.addCookie(cookie);
      }
    }
    filterChain.doFilter(request, response);
  }

我相信我的过滤器的组织方式有问题,但我已经尝试了所有的方法,从将不同的 http.httpBasic() 部分合并成一个组,到对 csrf() 使用 antIgnores,再到不处理 GET 请求中的 CSRF 标记。 如果有任何指导或建议,我们将非常感激。

如果您还有其他需要,请告诉我,我会尽力提供。

谢谢!我在使用GET请求时遇到了一些奇怪的行为。

angular spring-boot csrf x-xsrf-token
1个回答
0
投票

我怀疑是过滤的顺序出了问题。 在Spring-Boot Security中建立了一个过滤器层次结构。 XSRF-TOKEN需要在向cookie添加值之前生成。 如果在新的值生成之前,旧的值被添加到Cookie中,那么在浏览器刷新之前,前端和后端将不同步。

这也是为什么我把过滤顺序加在最后的原因。 如果有人有更好的切入点,我愿意游戏相应的更新,并更新这个答案来反映。

@Override
protected void configure(HttpSecurity http) throws Exception {
CsrfHeaderFilter csrfHeaderFilter = new CsrfHeaderFilter();

http.httpBasic()
    .authenticationEntryPoint(new AuthenticationFailureHandler())
    .and()
        .authorizeRequests()
        .antMatchers("List of API URI").permitAll()
        .anyRequest().authenticated();

// Configurations for CSRF end points
http.httpBasic()
    .authenticationEntryPoint(new AuthenticationFailureHandler())
    .and()
        .csrf()
        .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
    .and()
        .authorizeRequests()
        .antMatchers("Login API URI").permitAll()
    .and()
        .addFilterAfter(csrfHeaderFilter, ExceptionTranslationFilter.class);

    // Logout configurations
    http.logout()
    .permitAll()
    .logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
© www.soinside.com 2019 - 2024. All rights reserved.