The following property exists:
security.enable-csrf=false
BUT csrf protection is still on if I add the property to application.properties
.
What works is to disable it programatically.
But I'd prefer properties configuration. Why could it not be working?
@Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable();
}
}
To protect MVC applications, Spring adds a CSRF token to each generated view. This token must be submitted to the server on every HTTP request that modifies state (PATCH, POST, PUT and DELETE — not GET). This protects our application against CSRF attacks since an attacker can't get this token from their own page.
As of Spring Security 4.0, CSRF protection is enabled by default with XML configuration. If you would like to disable CSRF protection, the corresponding XML configuration can be seen below. CSRF protection is enabled by default with Java Configuration.
Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.
But till now in all our examples we had disabled CSRF. CSRF stands for Cross-Site Request Forgery. It is an attack that forces an end user to execute unwanted actions on a web application in which they are currently authenticated.
As the WebSecurityConfigurerAdapter
uses an imperative approach you can inject the value of the security.enable-csrf
variable and disable CSRF when it be false. You are right, I think this should work out of the box.
@Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Value("${security.enable-csrf}")
private boolean csrfEnabled;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
if(!csrfEnabled)
{
http.csrf().disable();
}
}
}
What I did was to set that variable to false in my application.yml for when I had a dev spring profile active, although you could create a profile called nosecurity for such purposes too. It eases this process a lot:
--- application.yml ---
# Production configuration
server:
port: ${server.web.port}
admin.email: ${admin.email}
#etc
---
spring:
profiles: dev
security.enable-csrf: false
#other Development configurations
I hope it suits your needs
Based on a comment of a Spring Boot member this issue is fixed on new versions of Spring: I had it on version 1.5.2.RELEASE
but it seems that in version 1.5.9.RELEASE (the latest stable one to the date before version 2) its already fixed and by default csrf is disabled and it can be enabled with security.enable_csrf: true
. Therefore a possible solution could be just upgrading to version 1.5.9.RELEASE
, before making a major one to version 2 where the architecture might be quite more different.
An update:
Looks like there is an issue with disabling CSRF using application.properties on spring-boot 1.x (and thanks to Eliux for openning this case).
So my solution for spring-boot 1.5.7 with an embedded tomcat is disabling CSRF via SecurityConfig class (note that this way I keep the tomcat ootb basic authentication):
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// Note:
// Use this to enable the tomcat basic authentication (tomcat popup rather than spring login page)
// Note that the CSRf token is disabled for all requests (change it as you wish...)
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// Add here any custom code you need in order to get the credentials from the user...
auth.inMemoryAuthentication()
.withUser("myUserName")
.password("myPassword")
.roles("USER");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With