I'm trying to configure Spring Security to make it support CORS. Thanks to this post, Spring security CORS Filter, I've made it work on my localhost with Spring Boot with this configuration code :
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.antMatcher("/api/**")
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/login").permitAll()
.antMatchers(HttpMethod.GET, "/api/websocket/**").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.addFilterBefore(new JWTLoginFilter("/api/login", HttpMethod.POST, authenticationManager(), tokenAuthenticationService, myUserService), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class)
.csrf().disable();
}
@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;
}
}
But when I deploy my apps on remote Tomcat servers, it doesn't work :
Access to XMLHttpRequest at 'http://xxx:9080/yyy/api/user/findByLogin/?login=zzz' from origin 'http://xxx:10080' 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.
Here's a screenshot of the failing OPTIONS request :
And the working request on my localhost :
Is my configuration class enough or do I need to set something in Tomcat settings ? Thank you
Spring security provides a way to configure CORS in http configurer, there's a much cleaner approach to add CORS filter to the application-
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyCORSFilterClass implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
Ordering the filter with the highest precedence makes sure that MyCORSFilterClassimplementation of javax.servlet.Filter is the first one in the chain.
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