Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cors Error when using CorsFilter and spring security

I'm building an API Service using Spring Boot. It uses Basic Auth for the authentication. When clients try to connect to the API, they will get CORS error.

On the Spring Boot, it throws error

java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*"since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.

I have tried to find the example of allowedOriginPatterns usage but not found yet. Even for its document -https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/CorsRegistration.html#allowedOriginPatterns-java.lang.String... I still don't know what is the pattern I have to put inside config.allowedOriginPatterns();

Below is my CorsFilter code,

@Configuration
public class RequestCorsFilter {

    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Collections.singletonList("*"));
        config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "responseType", "Authorization"));
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }      

}

And here is my Authentication code,

@Configuration
@EnableWebSecurity
public class AuthenConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
        throws Exception {
    auth
    .inMemoryAuthentication()
    .withUser("thor").password("{noop}P@ssw00rd")
    .authorities("USER");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/v2/api-docs", 
            "/swagger-resources/**", 
            "/configuration/ui",
            "/configuration/security", 
            "/swagger-ui.html",
            "/webjars/**"
        };

        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers(AUTH_WHITELIST).permitAll() // whitelist URL permitted
            .antMatchers("/api").authenticated(); // others need auth
    }

}
like image 924
Hikaru Shindo Avatar asked Feb 05 '21 09:02

Hikaru Shindo


People also ask

How do I enable CORS in Spring security?

To enable CORS support through Spring security, configure CorsConfigurationSource bean and use HttpSecurity. cors() configuration.

How do you solve the CORS problem in spring boot?

Enable CORS in Controller Method We need to set the origins for RESTful web service by using @CrossOrigin annotation for the controller method. This @CrossOrigin annotation supports specific REST API, and not for the entire application.

How do you fix a CORS error?

To get rid of a CORS error, you can download a browser extension like CORS Unblock. The extension appends Access-Control-Allow-Origin: * to every HTTP response when it is enabled. It can also add custom Access-Control-Allow-Origin and Access-Control-Allow-Methods headers to the responses.

Can we add CORS without security in spring boot?

CORS must be processed before Spring Security because the pre-flight request will not contain any cookies (i.e. the JSESSIONID ). If the request does not contain any cookies and Spring Security is first, the request will determine the user is not authenticated (since there are no cookies in the request) and reject it.


2 Answers

Use config.setAllowedOriginPatterns("*") instead of config.setAllowedOrigins(Collections.singletonList("*"));

like image 61
stodi Avatar answered Sep 30 '22 11:09

stodi


config.setAllowedOrigins(Collections.singletonList("*"));

This line has to be changed. You should list all servers, that should have access to your application.

E.g. you use angular, so the development server for the frontend is http://localhost:4200. Your server in production is https://you.server.domain.com

Then your config List should look like this

config.setAllowedOrigins(List.of("http://localhost:4200","https://you.server.domain.com"));
like image 24
seism0saurus Avatar answered Sep 30 '22 11:09

seism0saurus