Spring Security拒绝注销CSRF令牌

时间:2015-06-10 12:32:26

标签: java angularjs spring spring-mvc spring-security

我正在尝试使用本教程实现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(显然适用于所有其他请求)。

1 个答案:

答案 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;
}