membersound
membersound

Reputation: 86925

How to disable csrf in Spring using application.properties?

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();

    }
}

Upvotes: 39

Views: 115356

Answers (7)

Benjamin James
Benjamin James

Reputation: 63

As Per Mar's answer, this is my full config class - without the crsf line it was returning 403 forbidden for Post but allowing Get, now allows Post as well:

@Configuration
public class Config {

    @Autowired
    EmissionsProperties properties;

    /**
     * Add configuration logic as needed.
     *
     **/
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        String ddaURL = properties.getDdaserverurl();
        http
                .csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .cors(cors -> cors.configurationSource(request -> {
                    CorsConfiguration configuration = new CorsConfiguration();
                    configuration.setAllowedOrigins(Arrays.asList(ddaURL));
                    configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
                    configuration.setAllowCredentials(true);
                    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                    source.registerCorsConfiguration("/**", configuration);
                    return configuration;
                }))
                .oauth2Login(Customizer.withDefaults());

        return http.build();
    }

}

Upvotes: 0

EliuX
EliuX

Reputation: 12685

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

Update on Dec 17th of 2017

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.

Update on Jun 02nd of 2023

The method http.csrf requires now a customizer of type Customizer<CsrfConfigurer<HttpSecurity>> to configure csrf. Therefore, instead of:

http.csrf().disable();

you should use

http.csrf(AbstractHttpConfigurer::disable);

Upvotes: 40

Pavel Azarenko
Pavel Azarenko

Reputation: 21

I guess: spring-security 6.1.4

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // ...
            .csrf((csrf) -> csrf
                .ignoringRequestMatchers("/api/*")
            );
        return http.build();
    }
}

Or

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // ...
            .csrf((csrf) -> csrf.disable());
        return http.build();
    }
}

See: Disable CSRF Protection

Upvotes: 2

Mars
Mars

Reputation: 101

For Spring Boot 3. It helped me:

http.csrf(csrf -> csrf.disable());

Upvotes: 9

Emmy Steven
Emmy Steven

Reputation: 143

For Spring Boot 3.1.0 (spring-boot-starter-web) use the code snippet below

http.csrf(AbstractHttpConfigurer::disable);

For Spring Boot 3.1.0 (spring-boot-starter-webflux) use the code snippet below

http.csrf(ServerHttpSecurity.CsrfSpec::disable);

Upvotes: 7

Larry Ricker
Larry Ricker

Reputation: 319

Was able to disable it with the following line in the spring-security.xml file:

<security:csrf disabled="true"/>

Upvotes: 1

Naor Bar
Naor Bar

Reputation: 2209

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

Upvotes: 6

Related Questions