Enabling cors in dropwizard not working
Adding to Mike Clarke's answer:
Setting the CHAIN_PREFLIGHT_PARAM
to false will let this filter handle preflight requests without your authentication filters intercepting what would be a 200
response and turning them into unauthorized / forbidden.
import org.eclipse.jetty.servlets.CrossOriginFilter;
import javax.servlet.DispatcherType;
import java.util.EnumSet;
public void run(Configuration conf, Environment environment) {
// Enable CORS headers
final FilterRegistration.Dynamic cors =
environment.servlets().addFilter("CORS", CrossOriginFilter.class);
// Configure CORS parameters
cors.setInitParameter("allowedOrigins", "*");
cors.setInitParameter("allowedHeaders", "X-Requested-With,Content-Type,Accept,Origin");
cors.setInitParameter("allowedMethods", "OPTIONS,GET,PUT,POST,DELETE,HEAD");
// Add URL mapping
cors.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
// DO NOT pass a preflight request to down-stream auth filters
// unauthenticated preflight requests should be permitted by spec
cors.setInitParameter(CrossOriginFilter.CHAIN_PREFLIGHT_PARAM, Boolean.FALSE.toString());
}
I was surprised that I didn't find any examples on the interwebs that included this configuration. Spent a few days trying to figure this out.
The bug here is that the filter hasn't been configured with a URL path via the addMappingForUrlPatterns
method.
This worked for me using dropwizard 0.7.1:
import org.eclipse.jetty.servlets.CrossOriginFilter;
import javax.servlet.DispatcherType;
import java.util.EnumSet;
public void run(Configuration conf, Environment environment) {
// Enable CORS headers
final FilterRegistration.Dynamic cors =
environment.servlets().addFilter("CORS", CrossOriginFilter.class);
// Configure CORS parameters
cors.setInitParameter("allowedOrigins", "*");
cors.setInitParameter("allowedHeaders", "X-Requested-With,Content-Type,Accept,Origin");
cors.setInitParameter("allowedMethods", "OPTIONS,GET,PUT,POST,DELETE,HEAD");
// Add URL mapping
cors.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
}
I'm assuming you're testing this live in a browser, but you can verify via CLI with a curl command like this:
$ curl -H "Origin: http://example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X OPTIONS --verbose \
http://localhost:8080
You should see a bunch of Access-Control-*
HTTP headers in the response.
For me even after configuring the above, it was not working. Ultimately it turned out that i have to also allow cache-control headers.
filter.setInitParameter("allowedHeaders",
"Cache-Control,If-Modified-Since,Pragma,Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");