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