I have an old project with Java backend on Spring version 4.3.4.RELEASE and Spring security version 4.2.2.RELEASE. There is no way to update the libraries, I have to work with what there is. The project is not REST API, does not have RestController nor WebMvcConfigurer. So, I configured cors as was suggested here :
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
protected SecurityConfiguration() {
super();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because our token is invulnerable
.csrf().disable()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
// allow anonymous resource requests
.antMatchers(HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers(HttpMethod.POST, "/rpc/*").permitAll()
.anyRequest().permitAll();
httpSecurity.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);
// disable page caching
httpSecurity.headers().cacheControl();
}
}
The Cors filter:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter extends OncePerRequestFilter {
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
logger.error("CORS filter: " + request.getMethod());
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, xsrf-token");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
In web.xml after all context-param and before listerenrs (that is the only filter in the app):
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>web.servlet.response.CorsFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I run the back end on localhost:8080 and front end on localhost:8081 However, when I try to send a POST request with application/json inside, there is an error in the browser console
Access to XMLHttpRequest at 'http://localhost:8080/rpc' from origin 'http://localhost:8081' 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.
Also, I would expect to see log "CORS filter: POST" on the back end, which I put there to check if it would make it to the filter, but there is no such log.
Please, any suggestions on why is it not working? I need to stick to application/json in requests, and there is also an Authorization header sometimes in the app, so can't avoid cors completely. Can this be an Angular 2 issue?