Spring boot custom response header blocked by CORS - spring-boot

I have Spring Boot application that provides GET REST API endpoint to a list of objects. The list has a default pagination and provides custom 'Link' HTTP header with info about the next and previous pages based on the current page in the navigation for the client to utilize.
Example of Link HTTP header
link: <http://localhost:8080/api/v1/articles?page=1&size=1>; rel="next", <http://localhost:8080/api/v1/articles?page=4&size=1>; rel="last"'
When the client and web server utilizes the same origin then the header is included. However, I am unable to include the link header in the response header when the client has different origin. The application has CORS configuration, but I couldn't find anything to make it include my custom header. Only default response headers are included.
Any idea how include custom HTTP headers in the CORS response?
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public SpringDataUserDetailsService customUserDetailsService() {
return new SpringDataUserDetailsService();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/admin").authenticated().and().formLogin();
}
}
-- EDIT 1 --
Response headers when the client is of the same origin as web server
Response headers when the client is on the other port

I found the solution to my problem. The custom headers must be exposed in CorsConfigurationSource bean.
Adding this line of code, allowed cross orgin requests to get the custom header 'Link' in response.
configuration.addExposedHeader("Link");

Related

Spring Security CORS Blocked By Policy

This should be easy, but of course since it's Spring Security, it's not.
I am attempting to access a relatively simple api running as a Spring Boot application from an Angular application. Angular makes the calls to the API just fine, but the backend blocks the request due to CORS policy:
I added the following to my Security configuration:
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://localtest.me:4200","http://localtest.me:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Bean
#Profile("dev")
public SecurityFilterChain devFilterChain(HttpSecurity http) throws Exception {
// define a custom filter, irrelevant to question
// #formatter:off
http
.addFilterAfter(filter, ConcurrentSessionFilter.class)
.authorizeRequests()
.antMatchers("/path1","/path2","/logout").permitAll()
.anyRequest().authenticated()
.and()
.cors();
// #formatter:on
return http.build();
}
This STILL does not prevent the CORS policy block.
I've also tried putting various iterations of #CrossOrigin (with and without origins argument):
on the Controller class
on the endpoint method itself
Am I making a simple error causing this?
Edit: I added breakpoints to Spring's CorsFilter, and they are not being hit.
Edit: Adding screenshot by request:
try to add this at the head ( beggining of your controller)
#CrossOrigin(origins = "http://localhost:{youy_angular_application_port}")
public class YourRestController {
}
Not the proudest and most beautiful solution, but some months ago, I also needed to expose some endpoints to my frontend, so my angular application could send requests to them.
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/user").allowedOrigins("http://localhost:4200");
registry.addMapping("/post").allowedOrigins("http://localhost:4200");
registry.addMapping("/post/").allowedOrigins("http://localhost:4200");
registry.addMapping("/user/{id}").allowedOrigins("http://localhost:4200");
registry.addMapping("/post/{id}").allowedOrigins("http://localhost:4200");
registry.addMapping("/post/user").allowedOrigins("http://localhost:4200");
registry.addMapping("/post/user/").allowedOrigins("http://localhost:4200");
registry.addMapping("/post/user/{id}").allowedOrigins("http://localhost:4200");
registry.addMapping("/user/").allowedOrigins("http://localhost:4200");
}
};
}
The bean can get implemented where ever, since its a bean. In my case I implemented it in the MainApplication.java class.
Okay, here's what happened.
At end-of-day the day before yesterday, some numbskull checked in a change to application.properties changing the context-root of the application.
The application was no longer being served at http://localtest.me:8000/api , it was being servered at http://localtest.me:8000/appname/api.
Effectively, I had a 404 error as much as I had a CORS error. Chrome didn't tell me that the path didn't exist, it just kept telling me it was blocked.

Setting CORS headers with spring-security OAuth

I've trying to set CORS headers for a OAuth Rest API:
#Configuration
#EnableWebSecurity
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.cors().and()
.authorizeRequests()
.antMatchers("/oauth/token", "/oauth/authorize**", "/publica")
.permitAll();
http.requestMatchers().antMatchers("/funds/**").and().authorizeRequests().antMatchers("/funds/**")
.access("hasRole('USER')");
...
However, I'm not seeing the CORS headers in the response (Postman, localhost) when I access /oauth/token:
No CORS headers e.g. Access-Control-Allow-Origin: * :(
Also, I'd like this setting to apply to all routes too (e.g. /funds) but just trying to get the /oauth/token route working first.
Do I have this in the correct place? How do I get the CORS headers to set for this /oauth/token route (and others)? As far as I'm aware, the default corsConfigurationSource ought to be picked up if defined.

No 'Access-Control-Allow-Origin' header is present on the requested resource (Spring)

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;
}

Spring CORS Filter problem in light of Spring Cloud microservices with Zuul

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

Spring Boot #EnableResourceServer unexpected 401 Unauthorized error [duplicate]

I have created two web applications - client and service apps.The interaction between client and service apps goes fine when they are deployed in same Tomcat instance.
But when the apps are deployed into seperate Tomcat instances (different machines), I get the below error when request to sent service app.
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 401
My Client application uses JQuery, HTML5 and Bootstrap.
AJAX call is made to service as shown below:
var auth = "Basic " + btoa({usname} + ":" + {password});
var service_url = {serviceAppDomainName}/services;
if($("#registrationForm").valid()){
var formData = JSON.stringify(getFormData(registrationForm));
$.ajax({
url: service_url+action,
dataType: 'json',
async: false,
type: 'POST',
headers:{
"Authorization":auth
},
contentType: 'application/json',
data: formData,
success: function(data){
//success code
},
error: function( jqXhr, textStatus, errorThrown ){
alert( errorThrown );
});
}
My service application uses Spring MVC, Spring Data JPA and Spring Security.
I have included CorsConfiguration class as shown below:
CORSConfig.java:
#Configuration
#EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("*");
}
}
SecurityConfig.java:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
#EnableWebSecurity
#ComponentScan(basePackages = "com.services", scopedProxy = ScopedProxyMode.INTERFACES)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("authenticationService")
private UserDetailsService userDetailsService;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().fullyAuthenticated();
http.httpBasic();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.csrf().disable();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
}
Spring Security dependencies:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
I am using Apache Tomcat server for deployment.
CORS' preflight request uses HTTP OPTIONS without credentials, see Cross-Origin Resource Sharing:
Otherwise, make a preflight request. Fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag and the block cookies flag set, using the method OPTIONS, and with the following additional constraints:
Include an Access-Control-Request-Method header with as header field value the request method (even when that is a simple method).
If author request headers is not empty include an Access-Control-Request-Headers header with as header field value a comma-separated list of the header field names from author request headers in lexicographical order, each converted to ASCII lowercase (even when one or more are a simple header).
Exclude the author request headers.
Exclude user credentials.
Exclude the request entity body.
You have to allow anonymous access for HTTP OPTIONS.
Spring Security 3
Your modified (and simplified) code:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable();
}
You still need your CORS configuration (probably with some additional values):
#Configuration
#EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("*");
}
}
Spring Security 4
Since Spring Security 4.2.0 you can use the built-in support, see Spring Security Reference:
19. CORS
Spring Framework provides first class support for CORS. 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.
The easiest way to ensure that CORS is handled first is to use the CorsFilter. Users can integrate the CorsFilter with Spring Security by providing a CorsConfigurationSource using the following:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// by default uses a Bean by the name of corsConfigurationSource
.cors().and()
...
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Spring Security 5/6
For Spring Security 5/6 see Spring Security Reference:
CORS
Spring Framework provides first class support for CORS. CORS must be processed before Spring Security, because the pre-flight request does not contain any cookies (that is, the JSESSIONID). If the request does not contain any cookies and Spring Security is first, the request determines that the user is not authenticated (since there are no cookies in the request) and rejects it.
The easiest way to ensure that CORS is handled first is to use the CorsFilter. Users can integrate the CorsFilter with Spring Security by providing a CorsConfigurationSource that uses the following:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// by default uses a Bean by the name of corsConfigurationSource
.cors(withDefaults())
...
return http.build();
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
With Spring Security 5/6 you don't need to configure CORS twice (Spring Security and Spring MVC):
If you use Spring MVC’s CORS support, you can omit specifying the CorsConfigurationSource and Spring Security uses the CORS configuration provided to Spring MVC:
Since Spring Security 4.1, this is the proper way to make Spring Security support CORS (also needed in Spring Boot 1.4/1.5):
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
}
}
and:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// http.csrf().disable();
http.cors();
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH"));
// setAllowCredentials(true) is important, otherwise:
// The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
// setAllowedHeaders is important! Without it, OPTIONS preflight request
// will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Do not do any of below, which are the wrong way to attempt solving the problem:
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
web.ignoring().antMatchers(HttpMethod.OPTIONS);
Reference: http://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html
In my case, I have Resource Server with OAuth security enabled and any of above solutions didn't work. After some debugging and googling figured why.
#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(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
Basically in this example Ordered.HIGHEST_PRECEDENCE is key!
https://github.com/spring-projects/spring-security-oauth/issues/938
Various pom dependencies add different kinds of filters and therefore we could have issues based on order.
Add the below configuration in the main application. It worked me in spring boot application 2.3.1
package com.example.restservicecors;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#SpringBootApplication
public class RestServiceCorsApplication {
public static void main(String[] args) {
SpringApplication.run(RestServiceCorsApplication.class, args);
}
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedHeaders("*").allowedMethods("*");
}
};
}
}
Reference source: https://spring.io/guides/gs/rest-service-cors/
Since none of this posted examples helped me, I've taken things in my own knowledge.
In this method:
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration cors = new CorsConfiguration();
cors.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE"));
UrlBasedCorsConfigurationSource source = new
UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
CorsConfiguration by default have allowed method: POST, HEAD, GET, so PUT, DELETE will not work. What I did is I created a new instance of CorsConfiguration and set allowed methods:
cors.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE"));
so now my method looks like:
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration cors = new CorsConfiguration();
cors.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", cors.applyPermitDefaultValues());
return source;
}
Of course, all other configuration is made by Spring documentation.
Try this:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Arrays;
import java.util.List;
#Component
public class CorsFilterConfig {
public static final List<String> allowedOrigins = Arrays.asList("*");
#Bean
public FilterRegistrationBean<CorsFilter> initCorsFilter() {
// #formatter:off
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
config.addAllowedMethod("*");
config.setAllowedOrigins(allowedOrigins);
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
// #formatter:on
}
}
You can easily add the #CrossOrigin annotation to allow all of them if you use UsernamePasswordAuthenticationFilter. And in the security configurations the http.cors().and(). This worked for me.
#CrossOrigin(origins = "*")
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
#Override
protected void configure(HttpSecurity http) throws Exception {
CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter(authenticationManagerBean());
customAuthenticationFilter.setFilterProcessesUrl("/api/login");
http
.csrf().disable();
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// We can ant match out paths to the corresponding roles --> we allow certain roles to access certain API's
http
.cors()
.and();
http
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/**").permitAll();
...
This worked for: spring-boot-starter-parent 2.2.6.RELEASE
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedHeaders("*").allowedMethods("*");
}
}
Change "*" to something meaningful in prod

Resources