【问题标题】:Spring Security CookieBasedCSrf not workingSpring Security CookieBasedCSrf 不起作用
【发布时间】:2026-01-20 21:10:01
【问题描述】:

我正在开发一个带有 Angular2 前端的 RESTful Spring 后端。我将访问令牌(JWT 实现)存储在 httpOnly Cookie 中。为了保护自己免受对 post 请求的 XSRF 攻击,我需要在所有页面上启用 XSRF 保护,登录页面除外。根据 Spring Security 指南here,我启用了CookieCsrfTokenRepository

但是,当我点击公共 API (GET) 时,XSRF-TOKEN 未设置。此外,当我从 Angular2 提交登录表单数据时,系统会出现“无效的 csrf 令牌”错误。下面是我的WebSecurityConfig

    http
       .csrf()
           .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
           .and()
       .exceptionHandling()
           .authenticationEntryPoint(this.authenticationEntryPoint)
           .and()
       .sessionManagement()
           .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
           .and()
       .authorizeRequests()
           .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point
           .antMatchers(TOKEN_CSRF_ENTRY).permitAll()
           .and()
       .authorizeRequests()
           .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected API End-points
           .and()
       .cors()
           .and()
       .addFilterBefore(buildAjaxLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
       .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);

【问题讨论】:

    标签: spring spring-mvc spring-security


    【解决方案1】:

    您是否尝试过启用withCredentials: true? 这就是我在 Angular2 中编写帖子服务器的方式。

    this.http.request(
      path,
      {
        method: RequestMethod.Post,
        body: body,
        headers: customHeaders,
        withCredentials: true
      }
    )
    .map...
    .catch...
    

    我在WebSecurityConfig 有相同的配置。 我确实有一个使用 Angular 2 和使用 CookieCsrfTokenRepository 的 Spring Boot 的工作示例。

    My Angular 2 API service

    My WebSecurityConfig

    Github 仓库:angular-spring-starter

    【讨论】:

      【解决方案2】:

      您不应该通过 HTTP GET 获取 CSRF 令牌,请参阅 Spring Security Reference

      使用正确的 HTTP 动词

      防范 CSRF 攻击的第一步是确保您的网站使用正确的 HTTP 动词。具体来说,在使用 Spring Security 的 CSRF 支持之前,您需要确定您的应用程序正在使用 PATCH、POST、PUT 和/或 DELETE 来处理任何修改状态的内容。

      这不是 Spring Security 支持的限制,而是正确预防 CSRF 的一般要求。原因是在 HTTP GET 中包含私有信息会导致信息泄露。有关使用 POST 而不是 GET 获取敏感信息的一般指导,请参阅 RFC 2616 Section 15.1.3 Encoding Sensitive Information in URI’s

      您不应将登录排除在 CSRF 保护之外,请参阅Spring Security Reference

      登录

      为了防止伪造登录请求,登录表单也应该被保护免受 CSRF 攻击。

      但是您可以从 CSRF 保护中排除一些 URL 并包含一些 HTTP 动词,请参阅Spring Security Reference

      您还可以指定自定义 RequestMatcher 来确定哪些请求受 CSRF 保护(即,您可能不在乎是否利用了注销)。简而言之,如果 Spring Security 的 CSRF 保护的行为不完全符合您的要求,您可以自定义该行为。有关如何使用 XML 进行这些自定义的详细信息,请参阅 Section 41.1.18, “<csrf>” 文档,有关在使用 Java 配置时如何进行这些自定义的详细信息,请参阅 CsrfConfigurer javadoc。

      【讨论】:

        最近更新 更多