Spring Security拒绝注销CSRF令牌 [英] Spring Security denies logout CSRF token

查看:248
本文介绍了Spring Security拒绝注销CSRF令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用本教程来实现Angular应用: https://spring.io/guides/tutorials/spring-security-and-angular-js/

I'm trying to implement an Angular app using this tutorial: https://spring.io/guides/tutorials/spring-security-and-angular-js/

登录作品并执行后续的HTTP调用也同样有效. Angular成功地添加了CSRF令牌,而Spring成功地对其进行了解析.假设令牌为foo,则请求将包含以下标头:

Logging in works and performing subsequent HTTP calls works, too. Angular successfully appends the CSRF token and Spring successfully parses it. Assuming the token is foo, the requests will contain these headers:

Cookie:JSESSIONID=...; XSRF-TOKEN=foo

X-XSRF令牌:foo

X-XSRF-TOKEN: foo

现在,当尝试注销时 $http.post('logout', {}),Angular将使用完全相同的标头.但是,Spring会给出403的答案:

Now, when trying to log out with $http.post('logout', {}), Angular will use exactly the same headers. However, Spring answers with a 403:

在请求参数'_csrf'或标头'X-CSRF-TOKEN'上发现无效的CSRF令牌'null'.

Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.

这是我的安全配置的样子:

This is what my security configuration looks like:

protected void configure(HttpSecurity http) throws Exception {
    http
        .httpBasic().and()
        .authorizeRequests()
        .antMatchers("/").permitAll()
        .anyRequest().authenticated().and()
        .logout().and()
        .addFilterBefore(new CsrfHeaderFilter(), CsrfFilter.class);
}

CsrfHeaderFilter是该教程中解释的类 (显然适用于所有其他请求).

CsrfHeaderFilter is the class explained in the tutorial (which apparently works for every other request).

推荐答案

我意识到已经晚了2个月,但是今天我遵循的是完全相同的指南,而这个无人问津的帖子不断出现,所以这里是解决方法.

I realize it's 2 months late, but I was following the exact same guide today and this unanswered post keeps on popping up so here's the solution.

基本上,您缺少HttpSecurity配置程序中的csrfTokenRepository()配置.

Basically, you were missing the csrfTokenRepository() configuration in the HttpSecurity configurer.

Spring CsrfTokenRepository需要标头"X-CSRF-TOKEN",但是Angular在名为"X-XSRF-TOKEN"的标头中发送令牌,因此:

Spring CsrfTokenRepository expects the header "X-CSRF-TOKEN" but Angular sends the token in a header called "X-XSRF-TOKEN" so the guide recommended you setup an instance of CsrfTokenRepository which expects the Angular default header "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;
}

这篇关于Spring Security拒绝注销CSRF令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆