CORS issue with website calling a REST API on https - spring-boot

I have a website running on https.
I want this website to communicate with a REST Api service running on a AWS EC2 server.
This service is implemented with Spring Boot and the Controller class contains the #CrossOrigin annotation with the origin website as a parameter.
However I am getting following error while doing a POST request from the website with the service listening on port 443 with a self signed certificate:
Access to XMLHttpRequest at x from origin y 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.
And following one while doing a GET request:
Access to XMLHttpRequest at x from origin y has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I also declared localhost in the service #CrossOrigin annotation.
It is failing with same error as above if I have my service run on port 443 with a self signed certificate, but it is working fine if I have my service running on port 8080 without SSL.
Do you know what I am doing wrong?
Also I guess that if I manage to solve the CORS issue I will still have a problem, as my certificate is self signed.
How can I install a public certificate for a REST Api running in EC2 for example?
Thanks!

Add the config mentioned below to your spring-boot project.
#Configuration
public class CorsConfig {
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}

Related

Spring Auth Server 1.0.0 (w/ Spring Boot 3.0.0) CORS configuration not working for .well_known endpoints

I am trying to use the Spring Boot Auth Server sample code with a ReactJS frontend that will be hosted as a separate service. However, I am getting the following error.
localhost/:1 Access to fetch at 'https://8f5d3990e976.ngrok.io/.well-known/openid-configuration' from origin 'http://localhost:3000' has been blocked by CORS policy: 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.
I'm trying to configure CORS mentioned in this comment.
https://github.com/spring-projects/spring-authorization-server/issues/110#issuecomment-707964588
The class WebSecurityConfigurerAdapter was deprecated and removed so I added it a little differently.
#Bean
#Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/oauth2/**", config);
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.cors().configurationSource(source);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
// #formatter:off
http
.exceptionHandling(exceptions ->
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
// #formatter:on
return http.build();
}
Note: The reason I added the source with a local variable is I got this IDE error
If anyone would be able to help with this I would greatly appreciate it. Cheers.

How deactivate CORS in a Spring Boot API (Version 2.2.6)

I am currently working on a React Front-End with an already existing Spring Boot Backend.
When developing locally i ran into the typicall CORS Error:
Access to fetch at 'http://localhost:8180/api/data/firms' from
origin 'https://localhost:8087' 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.
runtime.js:98 GET http://localhost:8180/api/data/firms net::ERR_FAILED
I already tried most of the solutions mentioned in this post however nothing really helped. By adding one of these snippets
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
}
#Bean
public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
or creating a CorsFilter the CORS Error was gone but now the API always returned a HTTP 500 Error.
Does anyone know a solution for my problem?
You can add this in your controller class.
#CrossOrigin(origins = "${cross.origin}")
#RestController
application.properties
cross.origin=https://localhost:8087
I've added new answer for Spring Boot.
Additionally, if you are using create-react-app, you will avoid CORS problem to set up proxy.
(In this case, it is not required to change Spring Boot settings.)
package.json:
"proxy": "http://localhost:8180",

How can I authenticate a Ribbon load balancer and Zuul proxy using a certificate?

I have a Spring application, that acts as an authentication proxy for two backend servers. A user will access the Spring application and be forwarded to the backend once he is successfully authenticated. To prevent unwanted access without prior authentication the backend servers require a certificate as authentication.
My Spring application uses Netflix-Ribbon as a load balancer and Netflix-Zuul as a Proxy for the users requests. How can I configure them to use the client certificate that is required for the authentication on the backend servers?
Ok, I figured it out. You can configure your own CloasableHttpClient as a #Bean and create a custom SSL context. You can provide a certificate to a server through .loadKeyMaterial(). Zuul will then use these settings.
#Configuration
public class HttpClientConfig {
#Bean
public CloseableHttpClient httpClient() throws Throwable {
String keyPassphrase = "yourCertificatePassword";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("Path/to/your/clientCert.pfx"), keyPassphrase.toCharArray());
SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(keyStore, keyPassphrase.toCharArray())
.build();
return HttpClients.custom()
.setSSLContext(sslContext)
.build();
}
}

Disabling open-in-view in spring boot makes CORS stop working

I have a working CORS configuration in my spring boot app. I wanted to manage transactions on my own, so I decided to disable open-in-view in my application.yaml by setting it to false:
spring:
jpa:
open-in-view: false
CORS config:
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("http://localhost:4200");
configuration.addExposedHeader("Authorization");
configuration.addExposedHeader("Concurrency");
configuration.addAllowedMethod("*");
configuration.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
For some reason I can not figure out, this prevents the CORS from working properly, browser keeps saying that:
Access to XMLHttpRequest at 'http://localhost:8080/api/batch' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Even though that header is actually present in the pre-flight OPTIONS request. Tomcat logs no exceptions or log entries of interest that could possibly explain this.

Spring 4.2's native Global CORS support won't work with CAS filterProcessesUrl

i am trying to switch to spring 4.2's native Global CORS support after i upgrade to spring-boot 1.3, but it seemed won't work with CAS filter process url(/login/cas).
Originally, i was using spring-boot 1.2.7 with spring 4.2 and spring-security 4.0.2, and using self made filtered based cors support. And either my own rest service or CAS ST validation URL worked well. After i upgraded to spring-boot 1.3 with coming in spring and spring-security version. It stopped working.
After some digging, fixed this by AddFilterBefore. So filtered based CORS seemed work well too with spring-boot 1.3.0 + spring-security-cas.
However, i want to use native Global CORS, but it seemed the CAS ST validation URL(/login/cas) can't be recognized, though other rest endpoints are OK.
Please help.
The setup is quite straight forward.
#Configuration
public class CorsConfiguration {
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
}
And following are some trafic:
Request URL:http://localhost:9000/login/cas?ticket=ST-1357-15aQrv93jGEUsQpQRF1P-cas01.example.org
Request Method:GET
Status Code:302 Found
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Thu, 19 Nov 2015 09:19:31 GMT
Expires:0
Location:http://localhost:9000/
Pragma:no-cache
Server:Apache-Coyote/1.1
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
and following are console errors:
XMLHttpRequest cannot load http://localhost:9000/login/cas?ticket=ST-1357-15aQrv93jGEUsQpQRF1P-cas01.example.org. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
CORS native support is done by default at Spring MVC HandlerMapping level, so it is expected that your CAS filter will not be CORS enabled, since it handles request earlier.
One option to consider is using the org.springframework.web.filter.CorsFilter we also provide with Spring Framework 4.2 with the AddFilterBefore approach.
Be aware that CorsConfiguration has not the same default configuration than #CrossOrigin or CorsRegistry, so you need to define most of the properties yourself, for example:
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // you USUALLY want this
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
source.registerCorsConfiguration("/**", config);
CorsFilter filter = new CorsFilter(source);
// ...

Resources