Issue
I am using Spring Boot version 2.0.2Release. Below is my security configuration
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
@ComponentScan("com.mk")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationProvider myAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.cors().configurationSource(corsConfigurationSource())
.and()
.csrf().disable()
.anonymous().and()
.authorizeRequests()
.antMatchers(HttpMethod.GET,"/index.html").permitAll()
.antMatchers(HttpMethod.POST,"/login").permitAll()
.antMatchers(HttpMethod.GET,"*").authenticated()
.and().httpBasic();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
I am unable to invoke any API (including login which is permitAll) because of CORS issue.
On Browser I am getting (It works with Postman, since CORS check is not made there)
Failed to load http://localhost:8080/myurl: 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:4200' is therefore not allowed access. The response had HTTP status code 403.
Solution
Although 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 MyCORSFilter 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 highest precedence makes sure that MyCORSFilter implementation of javax.servlet.Filter
is the first one in the chain. Hope this helps
Answered By - priteshbaviskar
Answer Checked By - Mildred Charles (JavaFixing Admin)