我正在尝试使用本教程实现Angular应用:https://spring.io/guides/tutorials/spring-security-and-angular-js/
登录工作并执行后续HTTP调用也可以。 Angular成功附加了CSRF令牌,Spring成功解析了它。假设令牌为foo
,请求将包含以下标题:
Cookie:
JSESSIONID=...; XSRF-TOKEN=foo
X-XSRF-TOKEN:
foo
现在,在尝试注销时
$http.post('logout', {})
,Angular将使用完全相同的标头。但是,Spring回答了403:
无效的CSRF令牌' null'在请求参数' _csrf'上找到或标题' X-CSRF-TOKEN'。
这就是我的安全配置:
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated().and()
.logout().and()
.addFilterBefore(new CsrfHeaderFilter(), CsrfFilter.class);
}
CsrfHeaderFilter是类explained in the tutorial(显然适用于所有其他请求)。
答案 0 :(得分:0)
我意识到它已经晚了2个月了,但是我今天也遵循完全相同的指南,这个未经回答的帖子一直在弹出,所以这就是解决方案。
基本上,您错过了csrfTokenRepository()
配置程序中的HttpSecurity
配置。
Spring CsrfTokenRepository
需要标头"X-CSRF-TOKEN"
,但Angular会在名为"X-XSRF-TOKEN"
的标头中发送令牌,因此the guide建议您设置CsrfTokenRepository
的实例Angular默认标题"X-XSRF-TOKEN"
:
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated().and()
.logout()
.and()
//This is the first part you were missing
.csrf()
.csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterBefore(new CsrfHeaderFilter(), CsrfFilter.class);
}
@Bean
public CsrfTokenRepository csrfTokenRepository(){
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
// This is the second part you were missing
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}