Spring 启动 -- Post 使用 CSRF 令牌的请求产生 403 错误
Spring Boot -- Post request with CSRF token produce 403 error
我正在尝试在我的 Spring 启动 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 的令牌是相同的,因为使用了 .addFilterAfter() 中的安全配置部分 CustomCsrfFilter.java,但是当我从此 CSRF_IGNORE,我得到的是 403,并且未使用 CustomCsrfFilter.java 中的 logger/debug,因此我认为未比较令牌。
我觉得我漏掉了什么,想了解一下
如果您想将 CSRF 与仅限 http 的假 cookie 一起使用,为什么不使用 Spring 内置的安全性 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 { }
我正在尝试在我的 Spring 启动 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 的令牌是相同的,因为使用了 .addFilterAfter() 中的安全配置部分 CustomCsrfFilter.java,但是当我从此 CSRF_IGNORE,我得到的是 403,并且未使用 CustomCsrfFilter.java 中的 logger/debug,因此我认为未比较令牌。
我觉得我漏掉了什么,想了解一下
如果您想将 CSRF 与仅限 http 的假 cookie 一起使用,为什么不使用 Spring 内置的安全性 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 { }