Spring Boot-使用CSRF令牌的发布请求会产生403错误

时间:2020-04-21 00:25:16

标签: java spring-boot csrf csrf-token

我正在尝试在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();
    }

其他与本教程中的内容相同。

我正在与邮递员进行测试。

当我在 CSRF_IGNORE 中添加所需的端点时,通过记录器/调试,我可以看到库存的令牌和cookie中的令牌是相同的,因为安全配置的部分 CustomCsrfFilter.java使用 .addFilterAfter()中的,但是当我从此CSRF_IGNORE中删除端点时,得到的是403,并且在 CustomCsrfFilter.java < / strong>未使用,因此我认为令牌没有被比较。

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

1 个答案:

答案 0 :(得分:2)

如果您想将CSRF与仅使用http的错误cookie一起使用,为什么不使用Spring Security内置的CookieCsrfTokenRepository?应该以这种方式简化您的配置。 CustomCsrfFilter似乎正在向XSRF-TOKEN does for youHttpServletResponse添加一个CookieCsrfTokenRepository cookie。

使用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 { }