I'm trying CORS with Spring security. So here is my WebSecurityConfigurerAdapter :
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("*"));
configuration.setAllowedMethods(List.of("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
And here is my WebMvcCofigurer :
@EnableWebSecurity
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer
{
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
}
}
But it gives me
from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Current code : SecurityConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.disable()//some stackoverflow solution(not accepted) said so
.csrf()
.disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login();
}
}
WebConfig.java:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebSecurity
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH")
.allowedHeaders("*")
.allowCredentials(true);
}
}
I tried even a filter(As it crashes when starting, so I removed it) MyCorsFilter.java
@Configuration
public class MyCorsFilter {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedHeader("*");//tried list and all other collection stuff
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);//tried with negative value
return bean;
}
}
Also tried
http
.headers()
.addHeaderWriter(
new StaticHeadersWriter(
"Access-Control-Allow-Origin",
"http://localhost:3000"))
And here is the OAuth2 configuration :
@Configuration
public class OAuth2Config {
@Bean
@RequestScope
public GoogleOAuth2 google(OAuth2AuthorizedClientService clientService) {
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
String accessToken = null;
if (authentication.getClass()
.isAssignableFrom(OAuth2AuthenticationToken.class)) {
OAuth2AuthenticationToken oauthToken =
(OAuth2AuthenticationToken) authentication;
String clientRegistrationId =
oauthToken.getAuthorizedClientRegistrationId();
if (clientRegistrationId.equals("google")) {
OAuth2AuthorizedClient client = clientService.loadAuthorizedClient(
clientRegistrationId, oauthToken.getName());
accessToken = client.getAccessToken().getTokenValue();
}
}
return new GoogleOAuth2(accessToken);
}
}
Recently I faced the exact same error as I was trying to integrate my angular application to enable authentication for JWT based authentication using spring security.
I see what you are missing in your security configuration. Maybe that is the problem.
First of all, if you configure everything related to CORS in your security configuration then you don't need to create filter or extend WebMvcConfigurer.
Below is what you are missing in your security config.
http.csrf().disable().cors().configurationSource(corsConfigurationSource())
Here is complete code I copied and pasted it from my working code which I fixed yesterday.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.configurationSource(corsConfigurationSource())
.and()
.csrf()
.disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login();
}
And then cors config code is which is almost same as yours.
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
//the below three lines will add the relevant CORS response headers
configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Remove your MyCorsFilter and WebConfig class. Both are not needed.
UPDATE:
CORS issue with Google Oauth2 for server side webapps
CORS issue while making an Ajax request for oauth2 access token
When you use the Authorization code grant (OAuth2 for backend apps - &response_type=code), you must redirect the browser to the /auth endpoint - you cannot use XHR for that. The user will be redirected back after authentication.
After redirecting to the /auth endpoint, user needs to see in an address bar that the page is from Google (trusted source) and Google may need to do some more redirects in order to authenticate the user and present the consent page. So using XHR is not possible.
You may use UrlBasedCorsConfigurationSource with CorsFilter as used below. Please comment or remove the other CORS configurations and try with it.
package com.learning.jhipster.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Arrays;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CorsFilter corsFilter;
public SecurityConfig(@Lazy CorsFilter corsFilter) {
this.corsFilter = corsFilter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.disable()//some stackoverflow solution(not accepted) said so
.csrf()
.disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login();
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With