I am implementing a Spring Boot application that is hosted on a Google App Engine Standard Environment.
I have configured CORS like this, following the official guide:
#Configuration
#EnableWebSecurity
class WebSecurityConfigurer : WebSecurityConfigurerAdapter() {
#Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http.csrf()
.disable()
.cors()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().antMatchers("/api/**").permitAll()
}
#Bean
fun corsConfigurationSource(): CorsConfigurationSource {
val configuration = CorsConfiguration()
configuration.allowedOrigins = listOf("*")
configuration.allowedMethods = listOf("GET", "POST", "OPTIONS", "PUT", "DELETE", "HEAD")
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", configuration)
return source
}
executing the following cURL I receive the AllowedOrigins header as it is necessary:
curl -H "Access-Control-Request-Method: GET" -H "Origin: http://foo" -X OPTIONS "localhost:8080/api/abc/list?lang=de"
Response:
HTTP/1.1 200
Access-Control-Allow-Origin: *
Now when I have deployed my Spring App to AppEngine, I can also cURL successfully.
HTTP/2 200
access-control-allow-origin: https://myfrontend.com
access-control-allow-methods: GET
access-control-allow-credentials: true
Unfortunately, my Frontend Application gets blocked with a 403
Access to fetch at 'https://mybackend.com/api/abc/list?lang=de' from origin 'https://myfrontend.com' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Any tips?
Thanks.
I think you missed the important part setting headers in cors.
Add this line
configuration.allowedHeaders = listOf("*")
I used this code :
Ref : https://blogs.ashrithgn.com/disable-cors-in-spring-boot/
I have two GAE project
Python based using angular 11
Spring boot based micro services std env
Imp : No other changes in app.yaml or as mentioned by spring at
https://spring.io/guides/gs/rest-service-cors/ will make any difference
#Configuration
public class CorsConfig {
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
Related
I have a basic Spring Authorization Server set up as a Spring Boot application. I am attempting to access this server via an angular application using angular-auth-oidc-client.
When I attempt to log in, I get this error:
Access to XMLHttpRequest at 'http://localhost:9000/mydomain/.well-known/openid-configuration' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I've made multiple attempts to fix this issue, but have been unsuccessful.
Relevant parts of the Configuration for the authorization server are below:
// #formatter:off
#Bean
public RegisteredClientRepository registeredClientRepository() {
// removed
}
// #formatter:on
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH"));
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
// #formatter:off
#Bean
#Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http
.formLogin(Customizer.withDefaults())
.cors().configurationSource(corsConfigurationSource());
return http.build();
}
// #formatter:on
That CORS Configuration seems to be wide open, but I'm still seeing the issue.
Am I just making a stupid mistake that I'm not seeing?
Edit: yes, I've configured that port and domain in application.yml:
server:
port: 9000
servlet:
context-path: /mydomain
I know there are a lot threads on the forum about this issue but still haven't figure out a solution.
So, I have deployed two applications in a private JVM/tomcat 8.5.30 on my vps. The one is my ROOT.war and the other one is the admin.war They were accesible from http://example.com and http://example.com/admin
Before I installed a ssl certificate everything worked fine. After installing it and forcing https redirect I am facing a problem with my admin.war (now they are both accesible from https://example.com and https://example.com/admin)
My admin works with a lot of jquery (I cannot change that) and I am getting this error every time I am trying to submit something
Access to XMLHttpRequest at 'http: //example.com/admin/add' from origin 'https: //example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
So I am trying to fix this via spring security. In my security configuration I have
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SiteSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and()
//.....
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers"));
configuration.addExposedHeader("Access-Control-Allow-Headers");
configuration.setAllowedMethods(Arrays.asList("POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
I do this for both my root app and my admin app ( I don't know if that's correct to do it for both of them). Still doesn't work.
Any help?
thanks!!
If you see Error
'http://example.com/admin/add' from origin 'https://example.com' has been blocked
There are 2 issues
1 I guess your /add API call is not getting redirected to https. Ideally it should be https://example.com/admin/add Either you resolve this
or
2 Change setAllowedOrigins in your Admin App to http as well like this
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com", "http://example.com"));
configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers"));
configuration.addExposedHeader("Access-Control-Allow-Headers");
configuration.setAllowedMethods(Arrays.asList("POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Given: angular frontend application sends requests to backend microservice through gateway microservice. The backend is in Spring Cloud.
Question: how to correctly configure CORS filters to get rid of the following error:
Access to XMLHttpRequest at 'http://gateway-service:5555/api/useful-service/myentities/' from origin 'http://localhost:4200' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:4200, http://localhost:4200', but only one is allowed.
That's what I have written so far:
Gateway Service
My main class in the gateway serivice has 3 annotations: #SpringBootApplication, #EnableZuulProxy and #Configuration. So as I don't confgigured any security thing I presume that the Spring Security is not being used therefore I need to configure Spring MVC's CorsFilter. I do that like this (comments are for future searchers):
#Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowCredentials(true);
//corsConfig.addAllowedOrigin("http://localhost:4200");
corsConfig.addAllowedOrigin("*"); //wildcard that will simply copy the value of the request's Origin header
// into the value of the Response's Access-Control-Allow-Origin header, effectively allowing all origins.
// You can add specific origins instead if you wish to limit them.
corsConfig.addAllowedHeader("*");
corsConfig.addAllowedMethod("OPTIONS");
corsConfig.addAllowedMethod("HEAD");
corsConfig.addAllowedMethod("GET");
corsConfig.addAllowedMethod("POST");
corsConfig.addAllowedMethod("PUT");
corsConfig.addAllowedMethod("DELETE");
corsConfig.addAllowedMethod("PATCH");
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", corsConfig);
return new CorsFilter(configSource);
}
Useful Service
The main class over here is annotated with #EnableResourceServer and #SpringBootApplication. According to my "business rules" I would like to have Spring authorization (url security, and in the future the method security also) so as I configured Spring Security in general and OAuth2 and in partucular I should configure security's cors filter as well. Here's relevant security snippet that enables cors:
#Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.cors(); // by default uses a Bean by the name of corsConfigurationSource
}
}
And that's how I configure the cors functionality of spring security:
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS", "DELETE", "PUT", "PATCH"));
configuration.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Unfortunatelly I got the error mentioned above, if you have an idea how to fix it please tale.
It seems that this problem was fixed with a DedupeResponseHeader-filter.
See https://github.com/spring-cloud/spring-cloud-gateway/pull/866
Why is my 'Access-Control-Allow-Credentials' no longer being sent in response to preflight calls (OPTIONS) under Spring Boot 2.0.x (2.0.1.RELEASE in my case)? Here is my Global CORS Configuration that works fine under Spring Boot 1.5.6:
#Configuration
public class CorsConfig {
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(
"http://localhost:3000",..)
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");
}
};
}}
My pom dependencies (I am doing my own security and avoiding Spring Security):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
My service call to the REST endpoints fails the preflight:
Failed to load http://localhost:8080/api/v5/sec/auth: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access.
I have verified that 'Access-Control-Allow-Credentials' header is indeed present in the case of Spring Boot 1.5.6 and missing under Spring Boot 2.0.1.
All the documentation I can find, including the latest on spring.io here, says my global configuration is still correct, even though WebMvcConfigurerAdapter appears to be deprecated now.
UPDATE:
Here are the response headers before and after the migrate:
Before Migrate (Spring Boot 1.5.6):
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
Content-Type: application/json;charset=UTF-8
Date: Day, dd Mon yyyy hh:mm:ss GMT
Transfer-Encoding: chunked
Vary: Origin
After Migrate (Spring Boot 2.0.1 - Access-Control-Allow-Credentials header missing, but others changed/added):
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: GET,HEAD,POST <-- My specified methods ignored
Access-Control-Allow-Origin: * <-- My specified origin ignored
Access-Control-Max-Age: 1800
Content-Length: 0
Date: Day, dd Mon yyyy hh:mm:ss GMT
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
This was missing from the Spring doc and many examples but the answer was very easy. I just saw the allowCredentials() method on CorsRegistry and added .allowCredentials(true) to the registry method chain and that added the Access-Control-Allow-Credentials header back in.
Also, I no longer use the deprecated WebMvcConfigurerAdapter, but now implement WebMvcConfigurer and override the addCorsMappings() method.
#Configuration
public class CorsConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(
"http://localhost:3000",..)
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.allowCredentials(true)
;
}
}
If you are using Spring Boot 2.0.x
CORS support is disabled by default and is only enabled once the management.endpoints.web.cors.allowed-origins property has been set. The following configuration permits GET and POST calls from the example.com domain:
management.endpoints.web.cors.allowed-origins=http://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
For more information refer
I'm using spring boot 2.0.2. I have the same issue, but I use the following code to fix it. Does anybody have the best way?
// Miss `Access-Control-Allow-Origin` header in response using this bean.
// #Bean
// CorsConfigurationSource corsConfigurationSource() {
// CorsConfiguration configuration = new CorsConfiguration();
// configuration.setAllowCredentials(true);
// configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
// configuration.addAllowedMethod("*");
// configuration.setAllowedOrigins(this.getAllowedOrigins());
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// source.registerCorsConfiguration("/**", configuration);
// return source;
// }
#Bean
public FilterRegistrationBean<CorsFilter> initCorsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
config.addAllowedMethod("*");
config.setAllowedOrigins(this.getAllowedOrigins());
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
Step 1 : Spring already has a CorsFilter even though You can just register your own CorsFilter as a bean to provide your own cofiguration.
#Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); // Provide list of origins if you want multiple origins
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
Step 2 : Annotate the controller with #CrossOrigin annotation.
This works for me (Kotlin):
#Configuration
class CorsConfig : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**")
}
}
I am running a jHipster instance with oAuth authentication and CORS enabled on the server. I've added the following bean:
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setAllowedMethods(Arrays.asList(new String[]{"GET", "PUT", "POST", "DELETE", "OPTIONS"}));
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/oauth/**", config);
return new CorsFilter(source);
}
and added .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll() to ResourceServerConfiguration configuration.
When I attempt to authenticate a user (using jHipster running on a server) from an app running locally on a browser, I get:
Request Method:OPTIONS - Status Code:401 Unauthorized
It seems CORS is not configured properly to handle pre-flight authentication POST requests.
I've tried to implement some solutions proposed at Spring Data Rest and Cors and Spring Data Rest and Cors to no avail.
Is this something specific that can be done in jHipster to enabled authentication to work from a browser or app (not running on the jhipster server)?
I uncommented lines of CORS
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
Added in SecurityConfiguration
**.antMatchers(HttpMethod.OPTIONS, "/**")**
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/login/**")
.antMatchers("/api/account/reset_password/init")
.antMatchers("/api/account/reset_password/finish")
.antMatchers("/test/**");
}
And it has been working so far.