global cors configuration does not work in spring boot but indivisual #CrossOrigins work - spring-boot

I have below configs:
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","HEAD","DELETE","PUT"));
configuration.setMaxAge(1l);
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
and security config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.antMatchers(
"/auth/**"
).permitAll()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.anyRequest().authenticated()
;
}
but this mix does not work. If I remove CorsConfigurationSource corsConfigurationSource() block and add #CrossOrigin(origins = "*", maxAge = 1) cors problems will gone!
but I want to register cors globally, what is the problem?
I use spring boot version 2, with spring security and some rest controllers.
(maxAge=1) added because of browser caching that waste a lot of my time!
(if by any chance, browser skips preflight step, why server does not check for origin in real call? that must be checked in server or in client by browser?)

Check by adding this property.
configuration.setAllowedHeaders(Arrays.asList("*"));

Related

403 error when requesting POST or PUT during Spring RestAPI development

I am trying to implement and use Rest API in a project to which Spring 5 + Spring Security 5 is applied.
When testing with Postman after running Tomcat locally
url: http://localhost:8080/api~
It has been confirmed that requests such as get, post, and put work normally.
I uploaded this project to https server and while testing the api on the server in local Postman,
A 403 forbidden error occurred in requests such as put and post, excluding get requests.
When I googled, it said that Spring Security's csrf problem + cors handling problem.
So I changed the code like that.
WebSecurityConfig
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
~
.anyRequest().permitAll()
.and()
.formLogin()
~
.and()
.logout()
~
.and()
.httpBasic().disable().cors().configurationSource(corsConfigurationSource())
.and()
.sessionManagement()
~
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
WebMvcConfig
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedOrigins("*");
}
Controller
#CrossOrigin("*")
But in freflight request it returns 200 normally, but in this request I still get 403.
Which part is wrong? I would appreciate it if you let me know :)
In your configuration add add Cors filter via the HttpSecurity builder.
i.e.
Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.........
This will enable cors preflight requests which are used by PUT and POST.
you should not need to include a CorsConfigurationSource, just make sure you have the #CrossOrigin annotation in your Controllers as well.

Spring Boot CORS not working with React app

So as the title mentions, I have a spring boot backend that serves a REST API to a React front end. I have been getting numerous CORS issues, and have tried multiple methods. I am not an expert on spring-security but would really appreciate some help solving this issue.
My CORS config
private static final String [] AUTH_WHITELIST = {
// -- Swagger UI v2
"/v2/api-docs",
"/swagger-resources",
"/swagger-resources/**",
"/configuration/ui",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**",
"/_ah/warmup",
"/ae/test",
// -- Swagger UI v3 (OpenAPI)
"/v3/api-docs/**",
"/swagger-ui/**",
// other public endpoints of your API may be appended to this array
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().configurationSource(corsConfigurationSource()).and().authorizeRequests()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.antMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.apply(new JwtTokenFilterConfigurer(jwtTokenProvider,userDetailsService));
}
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
//config.setAllowedOriginPatterns(Arrays.asList("/*"));
config.setAllowedOrigins(Arrays.asList("localhost:3000"));
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("*"));
config.setAllowCredentials(false);
source.registerCorsConfiguration("/**", config);
return source;
}
Your method is not annotated with #Bean, so I do not think Spring is automatically instantiating or injecting this configuration.
Try annotating the method with #Bean:
#Bean
public CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Collections.singletonList("localhost:3000"));
config.setAllowedHeaders(Collections.singletonList("*"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowCredentials(Boolean.FALSE);
source.registerCorsConfiguration("/**", config);
return source;
}

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.

Simple CORS setup is not working by adopting all means

The frontend server is running on localhost:8080 and try to do CORS PUT request to the Spring boot server running on localhost:1072
I googled all the possible solution to make the CORS request work.
However, it's only working by using Postman for the PUT request.
Got 401 on the Chrome browser.
How do I make the Spring server could take CORS requests.
Thanks!
Also, curious why Spring doesn't show the exception on the console and always give developers hard time lol
CORSConfig.java
#Configuration
public class CORSConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:8080");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
registry.addMapping("/**")
.allowedMethods("*").allowedOrigins("*");
}
}
WebSecurityConfig.java
#Override
protected void configure(HttpSecurity http) throws Exception {
if (h2ConsoleEnabled)
http.authorizeRequests()
.antMatchers("/h2-console", "/h2-console/**").permitAll()
.and()
.headers().frameOptions().sameOrigin();
http.csrf().disable()
.cors()
.and()
.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/v1/**","/articles/**", "/profiles/**", "/tags").permitAll()
.antMatchers(HttpMethod.PUT, "/v1/**","/articles/**", "/profiles/**", "/tags").permitAll()
.antMatchers(HttpMethod.POST, "/v1/**","/articles/**", "/profiles/**", "/tags").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
ArticleApi.java
#CrossOrigin(origins = "*")
#RestController
#RequestMapping(path = "/v1/groups/{groupId}/articles/{aId}")
public class ArticleApi {
#CrossOrigin(origins = "*")
#PutMapping
public String updateArticle(#PathVariable("groupId") String groupId,
#PathVariable("aId") String aId
) {
return
}
The 401 reponse is received when the pre-flight check for the CORS request fails. So, it might be that your cors is not setup correctly.When reading through your config it made the following observations :
If you are going to allow cross origin requests from all domains on all methods, you could remove the controller method level annotation #CrossOrigin(origins = "*") as it is already specified at class level.
You are providing two global configurations for the CORS config. One config with the bean order set as 0 accepts only origin http://localhost:8080 while that configured with spring security accepts all origin.Remove one and keep either of the two as per your need.
You could try removing the CORS configuration provided in the class CORSConfig. You have already provided cors configuration along with WebSecurityConfig. You could remove the cors configuration provided in the security config,either way it will work with just one configuration or try removing the below code :
#Configuration
public class CORSConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:8080");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
registry.addMapping("/**")
.allowedMethods("*").allowedOrigins("*");
}
}

How can the web page with Spring Boot load images from imgur?

My web page would ajax(GET) and get the blog data from RESTFul backend.
After I got the data, my js program would update the page.
The data I got contained HTML tag, like:
<p>Hello</p>
<img src="https://i.imgur.com/xxxxxx.jpg">
But after updated my web page, the 403 error was appeared because the images can not be obtain from imgur.
My web page was updated successfully except the images didn't load.
This is my WebSecurityConfigurerAdapter:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailService customUserDetailService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/", "/*.*", "/getPost/**", "/css/**", "/js/**", "/tinymce/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
//.loginPage("/Login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.customUserDetailService)
.passwordEncoder(this.getPasswordEncoder());
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*", "https://i.imgur.com"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers","Access-Control-Allow-Origin","Access-Control-Request-Method", "Access-Control-Request-Headers","Origin","Cache-Control", "Content-Type", "Authorization"));
configuration.setAllowedMethods(Arrays.asList("DELETE", "GET", "POST", "PATCH", "PUT"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
How can I fix this problem ?
Thanks!
I thought i solved it...
If I used http://127.0.0.1, the images from imgur could not be obtain.
But I was successful if I used real IP to connect my website.

Resources