1

I want to disable CORS completely in spring boot security but all what I have tried doesn't seems to work

I have tried to add custom Filters and injecting it as a bean, also I have tried to disable cors in WebSecurityConfigurerAdapter I have also tried to add the filter in configure HttpSecurity method.

these some links I have already tried:

1: CORS problems with spring boot security.

2: Spring security CORS Filter

my current Code state as such:


@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    private final CustomUserDetailsService customUserDetailsService;
    private final AuthConfigProperties authConfigProperties;

    public WebSecurityConfig(@Lazy CustomUserDetailsService customUserDetailsService, AuthConfigProperties authConfigProperties) {
        this.customUserDetailsService = customUserDetailsService;
        this.authConfigProperties = authConfigProperties;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(authConfigProperties.getBcryptRounds());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .requestMatchers()
                .antMatchers("/login", "/logout", "/oauth/authorize")
                .and()
                .logout()
                .deleteCookies("JSESSIONID")
                .permitAll()
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable();

        http.cors().disable();

    }


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

}

when I try to access the authentication server in front-end I get this error message:

Access to fetch at 'http://localhost:8089/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

suliman
  • 334
  • 6
  • 17
  • CORS is a browser side thing; you need to _enable_ it surely? Might help you to read [about CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) to understand what it is. – Boris the Spider Oct 03 '19 at 21:00
  • @BoristheSpider hmm, I am not questioning your answer but if it's browser why we allowed to configure it in Back-end side ? in both cases is there a way to disable it! I am trying to send my system to production but this issue keeps recurring. – suliman Oct 03 '19 at 21:16
  • 2
    Nope, there is no way to disable it. The browser restricts all JS running to the Single Origin Policy (SOP). CORS allows you to override SOP with the consent of the server - this is why it is server side. Your authentication server needs to respond to a preflight from the browser saying “yup, I trust that origin, go ahead”. – Boris the Spider Oct 03 '19 at 21:26
  • @BoristheSpider I've fix the issue by setting up a proxy, in order to make the response comes to the client-side the browser checks whether the value of Allow-Control-access-origin is equal to the requested origin. that is what I understood until now. if my comment does not make any sense please do correct me. thank you. – suliman Oct 03 '19 at 21:35

4 Answers4

3

this code do work:


import com.example.myAuthServer.service.CustomUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    private final CustomUserDetailsService customUserDetailsService;
    private final AuthConfigProperties authConfigProperties;

    public WebSecurityConfig(@Lazy CustomUserDetailsService customUserDetailsService, AuthConfigProperties authConfigProperties) {
        this.customUserDetailsService = customUserDetailsService;
        this.authConfigProperties = authConfigProperties;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(authConfigProperties.getBcryptRounds());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .requestMatchers()
                .antMatchers("/login", "/logout", "/oauth/authorize")
                .and()
                .logout()
                .deleteCookies("JSESSIONID")
                .permitAll()
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable();


    }


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

}

but in order to get red of the error shown in the original post you just need to make the browser knows that the requested server url have the same "Allow-Control-Access-Origin" response's url.

We can do this by applying a proxy in client-side, In my case I am using react.

add a file called setupProxy.js under src directory.

then write the following code:

const proxy = require("http-proxy-middleware");


module.exports = function (app) {
    app.use(proxy("/oauth/token", {target: "http://localhost:8089"})); // put your host and api
};

and use it like this:

fetch("/oauth/token", {
            method: "POST",
            body: qs.stringify(Auth.bodyForNewToken(username, password)),
            headers: {
                "Content-Type": "application/x-www-form-urlencoded",
                Authorization: "Basic " + btoa("<CLIENT>:<SECRET>")
            }
        });

this code is just a hint, YOU NEED TO CHANGE THE NECESSARY LINES!!!.

suliman
  • 334
  • 6
  • 17
0

One way you can handle it is to add an WebMvcConfigurer. Although using this you should have in consideration the environment profile (dev, prod,etc) and you can leave the WebSecurityConfigurerAdapter with the cors configuration default. (don't need to disable it)

An example:

@Configuration
public class WebMvc implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("*")
                .allowedOrigins("*");
    }
}
Ricardo
  • 409
  • 4
  • 22
  • 1
    I think it's the same as this post https://stackoverflow.com/a/58227186/10420300 but in a generic way, which also seems like a terrible idea. – suliman Oct 04 '19 at 10:11
  • No because this is a general proxy and you don't need to control N controllers, it will be applied in all routes and if you put @Profile("dev") for example there won't be any problem. Of course you can be more specific in the parameters but overall it will work – Ricardo Oct 04 '19 at 13:50
0

Update as on 2022, the class WebSecurityConfigurerAdapter is deprecated. Hence you need to provide bean of type SecurityFilterChain. You can use below code snippet to disable cors -


@EnableWebSecurity(debug = true)
public class SecurityConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .cors().disable()
                .build();
    }
}
im-pratham
  • 158
  • 1
  • 6
0

Hey guys when u using spring security , don't use .csrf().disable(); with

 @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("*")
                .allowedOrigins("*");
    }

together!

if you used to above code u should just in security add.csrf() and not use disable() after that again

Ali.Mojtahed
  • 2,537
  • 1
  • 15
  • 23