spring boot angular csrf令牌握手错误

Posted

技术标签:

【中文标题】spring boot angular csrf令牌握手错误【英文标题】:spring boot angular csrf token handshake error 【发布时间】:2020-11-20 11:58:18 【问题描述】:

所以我不断收到关于从前端(角度)到后端(springboot)的请求的错误。我假设我没有正确地将其从前端发送到后端。

弹簧安全配置:

 @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.httpBasic().disable()
                .csrf()
                .csrfTokenRepository (this.getCsrfTokenRepository())
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    

    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurerAdapter() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/**").allowedOrigins("http://localhost:4200");

            
        ;
    
    private CsrfTokenRepository getCsrfTokenRepository() 
        CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
        tokenRepository.setCookiePath("/");
        return tokenRepository;
    

角度请求:

 let url = "http://localhost:8080/api/v1/get_txt"
      this.http.get(url).subscribe(response => 
        console.log(response)

        // post request

        
      let _csrf = this.tokenExtractor.getToken() as string == null ? "test":this.tokenExtractor.getToken();
      const formData = new FormData();
      formData.append("name", "name")
      formData.append("_csrf", _csrf)
      let post = "http://localhost:8080/api/v1/testpost"

      this.http.post(post, formData, 
        headers: new HttpHeaders().set("X-XSRF-TOKEN", _csrf),//.set("Cookie", 'XSRF-TOKEN='+_csrf)
      )
        .subscribe(response => 
            console.log(response)
        )
      )

请求被发送的证明: sent csrf token

我还忘记提及的是我收到了 403 错误。 我会感谢每一个支持,但我不想禁用 csrf 令牌,也不想删除 spring boot 依赖;)

我如何获得令牌:

app.module.ts:

    import:[HttpClientXsrfModule.withOptions(cookieName: 'XSRF-TOKEN')]

app.component.ts
-> import
-> inject into constructor
let _csrf = this.tokenExtractor.getToken();

更新 我发现 spring boot 无法从请求中提取 cookie。 所以一定是角度请求的错……

【问题讨论】:

我认为标题名称是错误的。你可以试试X-CSRF-TOKEN吗?例如:headers: new HttpHeaders().set("X-CSRF-TOKEN", _csrf) @MarcoLucidi 感谢您的建议,但遗憾的是它也不起作用...... @MarcoLucidi 你非常接近。实际上,标题名称应该是 X-XSRF-TOKEN。 您能说说您使用的是哪个版本的 Angular 吗? 【参考方案1】:

您从 Angular 发送的标头名称旨在用作 HTTP 参数。在您的代码中,它将是let post = "http://localhost:8080/api/v1/testpost?_csrf=" + _csrf。 因此,当 CookieCsrfTokenRepository 设置为 CSRF 令牌存储库并且您想将其作为标头发送时,此令牌的默认标头名称为 X-XSRF-TOKEN (as described here):

this.http.post(post, formData, 
        headers: new HttpHeaders().set("X-XSRF-TOKEN", _csrf)
)
...

【讨论】:

感谢@kemot90 的帮助,但即使令牌的名称为 X-XSRF-TOKEN,它仍然会引发错误 403,是的,我还检查了令牌不为空,但它仍然不行=( 所以问题可能出在令牌本身。您能否发布如何使用tokenExtractor.getToken() 提取令牌? 我认为这不是问题,我认为 spring boot 不知何故无法识别它...... 尝试在 post 请求中重新发送 XSRF-TOKEN cookie,同时保留 X-XSRF-TOKEN 标头。

以上是关于spring boot angular csrf令牌握手错误的主要内容,如果未能解决你的问题,请参考以下文章

Angular集成Spring Boot,Spring Security,JWT和CORS

Spring(Spring Boot)如何向前端提供 CSRF 令牌?

Angular 2/Spring Security CSRF 实现问题

Spring Boot 不需要 CSRF 令牌

Angular 2 Spring Security CSRF 令牌

Spring + Angular 2 + Oauth2 + CORS 的 CSRF 问题