Reputation: 1133
I'm trying to add a CORS filter to my Spring web application but the filter is not being executed. I've followed the relevant steps here: https://spring.io/guides/gs/rest-service-cors/ to no avail. I'm not using Spring Boot. I'm bootstrapping my application using Spring's WebApplicationInitializer in a 3.0+ servlet spec container.
Everything else in my application is working: configuration classes, controllers, hibernate entities, etc.
Update 1:
The below answers worked for me by adding the filter to the servlet container:
container.addFilter("CorsFilter", CorsFilter.class)
.addMappingForUrlPatterns(null, false, "/*");
However, I'm curious why Spring Boot does not require this? They must automatically search for Filters and add them to the context. Is there a straightforward way to do this? It seems unfortunate that I have to create a filter and then add it to some list in another class. It'd be nice if they were automatically registered like in Spring Boot.
Relevant code snippets:
WebApplicationInitializer:
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(WebAppConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
AppConfig:
@Configuration
@ComponentScan
public class AppConfig {
}
WebAppConfig:
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@ComponentScan(basePackageClasses = AppConfig.class)
public class WebAppConfig extends WebMvcConfigurerAdapter {
}
CorsFilter:
@Component
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
HttpServletRequest httpRequest = (HttpServletRequest) request;
String origin = httpRequest.getHeader("Origin");
if (StringUtils.hasText(origin)) {
boolean isMyDomain =
Pattern.compile("^https://(.*?\\.)?mydomain.com(:\\d+)?$")
.matcher(origin)
.find();
if (isMyDomain) {
httpResponse.setHeader("Access-Control-Allow-Origin", origin);
} else {
httpResponse.setHeader("Access-Control-Allow-Origin", "mydomain");
}
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LoggerFactory.getLogger(getClass()).info("CorsFilter initiated");
}
@Override
public void destroy() {
LoggerFactory.getLogger(getClass()).info("CorsFilter destroyed");
}
}
Upvotes: 2
Views: 5152
Reputation: 1030
You have to just register your Filter in your AppInitializer
.
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(WebAppConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
//Added filter dynamically
javax.servlet.FilterRegistration.Dynamic corsFilter = container.addFilter("corsfilter", CORSFilter.class);
corsFilter.addMappingForUrlPatterns(null, true, "/*");
}
}
You can take reference of this github repository.
Upvotes: 1
Reputation: 1479
You could add like this:
container.addFilter("CorsFilter", CorsFilter.class)
.addMappingForUrlPatterns(null, false, "/*");
Upvotes: 1