简体   繁体   中英

Spring Security denies logout CSRF token

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

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 JSESSIONID=...; XSRF-TOKEN=foo

X-XSRF-TOKEN: foo

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

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 is the class explained in the tutorial (which apparently works for every other request).

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM