简体   繁体   中英

X-CSRF-TOKEN is not generated by Spring Boot

I followed the guide here: http://spring.io/guides/gs/rest-service/ to build my rest service example and now I am trying to enable the CSRF protection. I read that it should be enabled by default, so if I DON'T include:

http.csrf().disable()

in my WebSecurityConfigurerAdapter configuration, the CSRF protectection should be enabled by default, but it does not seem to to be the case. The problem is that the X-CSRF-TOKEN is not generated and not included in my HTTP response in any way. What am I expected to do, to have the x-csrf-token generated and included in the response and, of course, the csrf protection fully working?

I noticed that, with a similar spring mvc configuration, I get the x-csrf-token generated simply including:

< security:csrf disabled="false"/>

in my security configuration file. But, with spring boot maybe I am getting something wrong and there is no way to have the csrf token generated. Can anybody help me, perhaps pointing me to a working example? My security configuration is:

     @Override
     protected void configure(HttpSecurity http) throws Exception 
     {
        http
      // .csrf().disable()
      .authorizeRequests()
          .anyRequest()
          .authenticated()
      .and()
      .httpBasic()
      .authenticationEntryPoint(new RestAuthenticationEntryPoint())
      .and()
      .formLogin()
      .successHandler(new RestAuthenticationSuccessHandler())
      .failureHandler(new SimpleUrlAuthenticationFailureHandler())
      .and()
      .logout()
      .logoutSuccessHandler(new RestLogoutSuccessHandler());
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception 
{
    auth.userDetailsService(restUserDetailService);
}

To include the CSRF Token in your csrf protection, you can include CSRFTokenRepository to generate tokens. To illustrate in your case adding a simple line is enough:

 @Override protected void configure(HttpSecurity http) throws Exception { http. .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //HERE ! Defaults XSRF-TOKEN as cookie name and X-XSRF-TOKEN as header name .authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic() .authenticationEntryPoint(new RestAuthenticationEntryPoint()) .and() .formLogin() .successHandler(new RestAuthenticationSuccessHandler()) .failureHandler(new SimpleUrlAuthenticationFailureHandler()) .and() .logout() .logoutSuccessHandler(new RestLogoutSuccessHandler());}

Using Spring security 5.3.0.Final, one of the ways you can generate the CSRF token is by setting in the cookie by using the following code below.

 http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))

You also need to include the generated CSRF token in your request for the server to authorize.

<form>
    <input type="hidden" name="_csrf" value="${cookie['XSRF-TOKEN'].getValue()}" />
    //Code goes here
</form>

In the event you're using a JS framework, you need to include the token by setting it in the request header.

Here is an example for a JQuery ajax call.

// Get the CSRF token from the cookie
const csrfCookie= document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1');
// Add the CSRF token to each ajax request header
settings.beforeSend = function(xhr) {
  xhr.setRequestHeader('X-XSRF-TOKEN', springCsrfCookie);
};
$.ajax(settings);

There are other implementations that will suit your needs that are documented here by Spring. https://docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/reference/html5/#servlet-csrf

You can configure CookieCsrfTokenRepository . Store CSRF Token in a Cookie with Java Configuration

    @Override
    protected void configure(HttpSecurity http) {
        http
            .csrf(csrf ->
                csrf
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            );
    }

We had pretty similar issue during our security tests where we suspected that we accidentally disable csfr in configure method of websecurityconfig class,by default it is enabled. by changing the congfigure method as shown below , we had spring automatically generate csfr tokens.

websecurityconfig class configure method==>

@Override
protected void configure(HttpSecurity http) throws Exception {              

     http
     .authorizeRequests()
         .antMatchers("/", "/login","/loginError","/home","/interruption").permitAll()                                                          
         .antMatchers("/admin").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.HALLEYYNT01.role())  
         .antMatchers("/requests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.CCHALLEYLOGIN.role())
         .antMatchers("/solrequests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.SOLHALLEYLOGIN.role())
         .anyRequest().authenticated()
         .and()
     .formLogin()             
         .loginPage("/login")  
         //.failureUrl("/loginError")
         .loginProcessingUrl("/authenticate")
         .defaultSuccessUrl("/")            
         .and()
     .logout().clearAuthentication(true).invalidateHttpSession(true).deleteCookies("JSESSIONID")         
         .logoutSuccessUrl("/login");
         //.and() 
     //.exceptionHandling().accessDeniedHandler(accessDeniedHandler);    
}   

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