Spring Boot: enable the CSRF check selectively only for some requests

The following configurations can be used also to excluding URIs from CSRF protection.

In your Spring Security java configuration file you can configure the HttpSecurity object as follows in order to enable the CSRF check only on some requests (by default is enabled on all the incoming requests).

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {

    // Build the request matcher for CSFR
    RequestMatcher csrfRequestMatcher = new RequestMatcher() {

      private RegexRequestMatcher requestMatcher =
          new RegexRequestMatcher("/urls-with-csrf-check/**", null);

      @Override
      public boolean matches(HttpServletRequest request) {

          // Enable the CSRF
          if(requestMatcher.matches(request))
              return true;
              
          // You can add here any other rule on the request object, returning 
          // true if the CSRF must be enabled, false otherwise
          // ....

          // No CSRF for other requests
          return false;
      }

    }; // new RequestMatcher

    http
      // Enable csrf only on some request matches
      .csrf()
        .requireCsrfProtectionMatcher(csrfRequestMatcher)
        .and()
      // Other security configurations ...
      .authorizeRequests()
        .antMatchers(
            "/",
            "/signup",
            "/user/**")
            .permitAll()
        .anyRequest().authenticated()
        .and()
      .formLogin()
        .loginPage("/login")
        .permitAll()
        .and()
      .logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/login?logout")
        .permitAll();
    
    return;
  } // method configure
  
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) 
      throws Exception {
    
    // Authentication manager configuration  
    // ...
    
  }
  
}

In the configure function that takes an object of type HttpSecurity (line 6) you can create a RequestMatcher object containing any rule you want on incoming requests, than use the requireCsrfProtectionMatcher option (line 34) to enable the CSRF check only on requests that matches your rules.

Multiple URLs

If you have a list of urls where the CSFR protection should be enabled it can be used this RequestMatcher definition (in place of the above, between lines 9 to 29):

RequestMatcher csrfRequestMatcher = new RequestMatcher() {

  // Enabled CSFR protection on the following urls:
  private AntPathRequestMatcher[] requestMatchers = {
      new AntPathRequestMatcher("/**/verify"),
      new AntPathRequestMatcher("/**/login*")
  };
  
  @Override
  public boolean matches(HttpServletRequest request) {
    // If the request match one url the CSFR protection will be enabled
    for (AntPathRequestMatcher rm : requestMatchers) {
      if (rm.matches(request)) { return true; }
    }
    return false;
  } // method matches
  
};

Allow by HTTP methods

Advanced controls can be performed also on the HTTP request’s method:

RequestMatcher csrfRequestMatcher = new RequestMatcher() {

  private Pattern allowedMethods = 
    Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");

  @Override
  public boolean matches(HttpServletRequest request) {
    // CSRF disabled on allowedMethod
    return !(allowedMethods.matcher(request.getMethod()).matches());
  }

};

Disable the CSFR protection only on some specific URLs

Leave by default the CSFR protection enabled and disable it only on specific URL using this RequestMatcher:

RequestMatcher csrfRequestMatcher = new RequestMatcher() {
  
  // Always allow the HTTP GET method
  private Pattern allowedMethods = Pattern.compile("^GET$");
  
  // Disable CSFR protection on the following urls:
  private AntPathRequestMatcher[] requestMatchers = {
    new AntPathRequestMatcher("/login"),
    new AntPathRequestMatcher("/logout"),
    new AntPathRequestMatcher("/verify/**")
  };

  @Override
  public boolean matches(HttpServletRequest request) {
    // Skip allowed methods
    if (allowedMethods.matcher(request.getMethod()).matches()) {
      return false;
    }   

    // If the request match one url the CSFR protection will be disabled
    for (AntPathRequestMatcher rm : requestMatchers) {
      if (rm.matches(request)) { return false; }
    }

    return true;
  } // method matches

};

References

Categories

Category BootstrapCategory CoffeescriptCategory DrupalCategory GravCategory HTMLCategory JavascriptCategory JoomlaCategory jQueryCategory LaravelCategory MagentoCategory PHPCategory SharePointCategory SpringCategory ThymeleafCategory WordPressCategory Workflow

Comments

Developed and designed by Netgloo
© 2017 Netgloo