Reputation: 1658
I'm trying to configure Spring for CORS in order to use Angular web UI:
I tried this:
@Configuration
@ComponentScan("org.datalis.admin.config")
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
PropertySourcesPlaceholderConfigurer conf = new PropertySourcesPlaceholderConfigurer();
conf.setLocation(new ClassPathResource("application.properties"));
return conf;
}
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("127.0.0.1");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<CorsFilter>(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
Apache server with Angular FE is running with Wildly server on the same server so I configured 127.0.0.1 for source.
But still I get:
Access to XMLHttpRequest at 'http://123.123.123.123:8080/api/oauth/token' from origin 'http://123.123.123.123' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
auth:1 Failed to load resource: the server responded with a status of 404 (Not Found)
Do you know how I can fix this issue?
Second way that I tried:
@Configuration
@EnableResourceServer
public class ResourceSecurityConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("resource_id").stateless(true);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/users/**").permitAll()
.anyRequest().authenticated()
.and()
.cors().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.anyRequest()
.fullyAuthenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
@Bean
public CorsConfigurationSource corsConfigurationSources() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
With the second configuration I get has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
auth:1 Failed to load resource: the server responded with a status of 404 (Not Found)
What is the best way to achieve this result?
Upvotes: 9
Views: 4101
Reputation: 7788
Try changing your bean name to corsConfigurationSource removing the "s"
Documentation https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors
// by default uses a Bean by the name of corsConfigurationSource
Upvotes: 0
Reputation: 4520
You need to add @CrossOrigin
class level in your controller class like below
@CrossOrigin
public class SampleController {
// Your code goes here
}
annotation to your rest controller class
Upvotes: 2
Reputation: 3166
This is my working @Configuration
class to handle CORS requests used only in dev environment.
@Configuration
//@Profile(PROFILE_DEV)
public class CorsConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*");
}
};
}
}
You have also to configure Spring Security to ignore HttpMethod.OPTIONS
used by preflight request (as the exception you mentioned)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
//...
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
//others if you need
.antMatchers(HttpMethod.OPTIONS, "/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.exceptionHandling()
.and()
.headers()
.frameOptions()
.disable()
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/**").authenticated();
}
}
Because when you use cors you have Simple Request and Preflighted Request that triggers an HttpMethod.OPTIONS
Upvotes: 3
Reputation: 8324
I recommend you to use a WebMvcConfigurer, and in the addCorsMappings method set the CORS configuration.
Somethingo like this
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:9798")
.allowedMethods("POST", "GET")
//.allowedHeaders("header1", "header2", "header3")
//.exposedHeaders("header1", "header2")
.allowCredentials(true).maxAge(3600);
}
}
Here there is a link with a fully functional Spring with CORS project, just download and run it.
https://github.com/reos79/spring-cors
It has a html page (person.html) this page does nothing but call the service on the port (9797). So you need to load this project twice, once on port 9797 to load the service and the other on port (9798). Then on you browser you call the page person on the server localhost:9798 and it will call the service on localhost:9797, in the file application.properties I configured the port.
Upvotes: 2
Reputation: 6944
You need to tell Spring Security
to use the CORS Configuration you created.
In my project I configured Spring Security
in this way:
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/rest/protected/**")
.authenticated()
//Other spring sec configruation and then:
.and()
.cors()
.configurationSource(corsConfigurationSource())
}
Where corsConfigurationSource()
is:
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
boolean abilitaCors = new Boolean(env.getProperty("templating.oauth.enable.cors"));
if( abilitaCors )
{
if( logger.isWarnEnabled() )
{
logger.warn("CORS ABILITATI! Si assume ambiente di sviluppo");
}
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200","http://localhost:8080", "http://localhost:8180"));
configuration.setAllowedMethods(Arrays.asList( RequestMethod.GET.name(),
RequestMethod.POST.name(),
RequestMethod.OPTIONS.name(),
RequestMethod.DELETE.name(),
RequestMethod.PUT.name()));
configuration.setExposedHeaders(Arrays.asList("x-auth-token", "x-requested-with", "x-xsrf-token"));
configuration.setAllowedHeaders(Arrays.asList("X-Auth-Token","x-auth-token", "x-requested-with", "x-xsrf-token"));
source.registerCorsConfiguration("/**", configuration);
}
return source;
}
I hope it's useful
Angelo
Upvotes: 5
Reputation: 189
Your allowed origin is 127.0.0.1 but your client side has the ip 123.123.123.123. Try to change this:
config.addAllowedOrigin("127.0.0.1");
To this:
config.addAllowedOrigin("123.123.123.123");
Upvotes: 6