【问题标题】:Spring Boot -- Post request with CSRF token produce 403 errorSpring Boot - 使用 CSRF 令牌发布请求产生 403 错误
【发布时间】:2020-08-03 15:31:20
【问题描述】:

我正在尝试在我的 Spring Boot API 中实现 CSRF 令牌安全性以了解如何处理它。

我关注了this tutorial (server side part),这是我的安全配置:

private static final String[] CSRF_IGNORE = {"/api/login"};


protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf()
                .ignoringAntMatchers(CSRF_IGNORE)
                .csrfTokenRepository(csrfTokenRepository())
                .and()
                .addFilterAfter(new CustomCsrfFilter(), CsrfFilter.class)
                .exceptionHandling()
                .authenticationEntryPoint(new Http403ForbiddenEntryPoint() {
                })
                .and()
                .authenticationProvider(getProvider())
                .formLogin()
                .loginProcessingUrl("/api/login")
                .successHandler(new AuthentificationLoginSuccessHandler())
                .failureHandler(new SimpleUrlAuthenticationFailureHandler())
                .and()
                .logout()
                .logoutUrl("/api/logout")
                .logoutSuccessHandler(new AuthentificationLogoutSuccessHandler())
                .invalidateHttpSession(true)
                .and()
                .authorizeRequests()
                .anyRequest().authenticated();
    }

其他与教程相同。

我正在使用 Postman 进行测试。

当我在 CSRF_IGNORE 中添加我想要的端点时,我可以通过 logger/debug 看到存储的令牌,并且来自 cookie 的令牌是相同的,因为安全配置的部分 CustomCsrfFilter.java使用了 .addFilterAfter() 中的 ,但是当我从这个 CSRF_IGNORE 中删除端点时,我得到的是 403,以及 CustomCsrfFilter.java 没有使用,所以我认为没有比较令牌。

我想我错过了一些东西,我想了解一下。

【问题讨论】:

    标签: java spring-boot csrf csrf-token


    【解决方案1】:

    如果你想使用带有 http only false cookie 的 CSRF,为什么不使用 Spring Security 内置的CookieCsrfTokenRepository?应该以这种方式简化您的配置。 CustomCsrfFilter 似乎正在向HttpServletResponse 添加一个XSRF-TOKEN cookie,其中CookieCsrfTokenRepository does for you

    使用CookieCsrfTokenRepository 时默认的CSRF cookie 名称是X-CSRF-TOKEN,这是Angular 的HttpClientXsrfModule 使用的默认名称。当然,如果需要,您可以自定义。

    所以你的安全配置变成了:

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .csrf()
                        .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                    .and()
                    .exceptionHandling()
                        .authenticationEntryPoint(new Http403ForbiddenEntryPoint())
                    .and()
                        .authenticationProvider(getProvider())
                    .formLogin()
                        .loginProcessingUrl("/api/login")
                        .successHandler(new AuthentificationLoginSuccessHandler())
                        .failureHandler(new SimpleUrlAuthenticationFailureHandler())
                    .and()
                    .logout()
                        .logoutUrl("/api/logout")
                        .logoutSuccessHandler(new AuthentificationLogoutSuccessHandler())
                        .invalidateHttpSession(true)
                    .and()
                    .authorizeRequests()
                        .anyRequest().authenticated();
        }
    

    使用 Angular,您的应用模块将 HttpClientXsrfModule 作为

    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        HttpClientModule,
        HttpClientXsrfModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    【讨论】:

    • 您好,感谢您的回答。在寻求帮助之前,我尝试了内置的CookieCsrfTokenRepository,但它是一样的。现在,要以正确的方式进行操作,我尝试按照您所说的进行操作,这比添加 csrf 令牌存储库更简单。我还从安全配置中删除了我的自定义 csrf 过滤器。现在,我遇到了同样的问题。在不在.ignoringAntMatchers 中的端点上发布请求给我一个 403 错误。你有什么想法吗?
    • 没关系,它现在可以工作了,我只需要添加标题(在邮递员中)X-XSRF-TOKEN。现在,如果我明白了,我需要在我的前面,在标题中发送 cookie 中的令牌。
    • 感谢@Thomas 这对我帮助很大,在邮递员请求中添加了该标头:)
    • @drumonii,这与您的答案无关,但是您是否记得如何获得这样的安全配置格式?您是手动执行的,还是有用于设置的格式化配置?我一直没能找到它。
    • @BrentThoenen,我手动格式化了它。您可能希望使用// @formatter:off// @formatter:on,以便在您格式化整个安全配置类时,您的IDE 会忽略这些配置行。
    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 2020-11-20
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2017-11-02
    • 2020-11-02
    相关资源
    最近更新 更多