简体   繁体   中英

CORS Spring Security configuration - 404 No 'Access-Control-Allow-Origin' header is present on the requested resource

I am trying to setup CORS on my Java Spring project.

Separately I have an Angular CLI application with a login page, I would like to authenticate a user using my Spring API.

I am getting the error on the client

origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I get this on the server log:

No mapping found for HTTP request with URI [/authenticateUser]

I have tried a number of examples from other threads but the client error doesn't change so I am a bit confused where to configure cors

I have a AppSecurityConfig class which extends WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    User.UserBuilder users = User.withDefaultPasswordEncoder();

    auth.inMemoryAuthentication()
            .withUser(users.username("user1").password("password").roles("ROLE1"))
            .withUser(users.username("user2").password("password").roles("ROLE2"))
            .withUser(users.username("user3").password("password").roles("ROLE3"));
}

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.cors()
        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .formLogin()
            .loginPage("/loginPageUrl")
            .loginProcessingUrl("/authenticateUser")
            .permitAll();
}

My Angular service makes the request:

authenticateUser(json: any) {
return this.http.post('http://localhost:8085/authenticateUser'
  , json, {headers : new HttpHeaders()
    .set('Authorization', '')
    });

}

The json passed in is:

{ username: this.username, password: this.password }

Adding the following method to my AppSecurityConfig class resolved the 'No 'Access-Control-Allow-Origin' header is present on the requested resource' error.

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
    configuration.setAllowedMethods(Arrays.asList("GET","POST"));
    configuration.addAllowedHeader("content-type");
    configuration.addAllowedHeader("Access-Control-Allow-Origin");
    configuration.addAllowedHeader("Authorization");
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

In my opinion , missing Access-Control-Allow-Origin header shouldn't have anything to do with an end point missing mapping issue. That might be another issue but not related to CORS.

First you should examine request & response headers in browser network tab ( when UI makes requests to API ) to see if CORS related headers are really missing in response.

These headers begin with - Access-Control-Allow-* & the one that controls origin is - Access-Control-Allow-Origin

Your security config code , http.cors() tries to add a CorsFilter as per below logic ( pasting Java Doc of http.cors() )

Adds a CorsFilter to be used. If a bean by the name of corsFilter is provided, that CorsFilter is used. Else if corsConfigurationSource is defined, then that CorsConfiguration is used. Otherwise, if Spring MVC is on the classpath a HandlerMappingIntrospector is used.

So if you don't have provided as what being asked in above then you need to provide that.

Refer this answer esp. section 3. customize CORS config

If time permits, go through Spring provided filter org.springframework.web.filter.CorsFilter to understand logic.

Try this:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("http://domain1.com","http://domain2.com"
                    "http://domain3.com");
    }
}

Add addCorsMappings method to your configuration class and set allowed origins url which are urls of your Angular apps.

In your situation it will be:

registry.addMapping("/**").allowedOrigins("http://localhost:4200");

to allow requests from Angular app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM