CORS issue on Swagger UI
Can someone tell me why am i getting these errors.
GET http://127.0.0.1:9000/api-docs/service.json
200 OK 4ms swagger-ui.js (line 30261)
Unable to Load SwaggerUI /api-docs/ (line 83)
Cross-Origin Request Blocked: The Same Origin Policy disallows
reading the remote resource at http://127.0.0.1:9000/api-
docs/service.json. This can be fixed by moving the resource to the
same domain or enabling CORS.
uncaught exception: Can't read from server. It may not have the
appropriate access-control-origin settings.
I am trying to run Swagger UI on port say 9090 and the Swagger API documentation at 9000 and trying to display the documentation in the UI.
I have added the CORS filter on API Documentation server (port 9000) as follows.
FilterHolder cors = swaggerUIContext.addFilter(CrossOriginFilter.class,"/*",EnumSet.of(DispatcherTyp e.REQUEST));
cors.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
cors.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "");
cors.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD");
cors.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type, api_key, Authorization");
The Request and Response headers in firefox V33.0 are
Response Headers
Content-Length 428
Content-Type application/json
Request Headers
Accept application/json;charset=utf-8,*/*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Host localhost:9000
Origin http://localhost:9090
Referer http://localhost:9090/api-docs/
User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:33.0)
Gecko/20100101 Firefox/33.0
Here is how I am setting the CORS on server
final ResourceHandler swaggerUIResourceHandler = new ResourceHandler();
swaggerUIResourceHandler.setResourceBase("target/classes/api-docs");
final ServletContextHandler swaggerUIContext = new ServletContextHandler();
swaggerUIContext.setContextPath("/api-docs");
swaggerUIContext.setHandler(swaggerUIResourceHandler);
FilterHolder cors = swaggerUIContext.addFilter(CrossOriginFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
cors.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
cors.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
cors.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD");
cors.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type, api_key, Authorization");
ServletHolder def = new ServletHolder("default", DefaultServlet.class);
def.setInitParameter("resourceBase","./http/");
def.setInitParameter("dirAllowed","false");
swaggerUIContext.addServlet(def,"/");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { swaggerUIContext, new DefaultHandler() });
server.setHandler(handlers);
Did you do something funky with the json file?
I faced the same error, while trying to modify my JSON file and seeing the changes on Chrome. Ensure that the json itself is not breaking somehow, an extra bracket, comma and so on. I started from scratch with one of the example json from the swagger live demo and I was fine. I know it's a task but worked for me, atleast the UI loaded!
You can also go through the swagger ui readme, CORS support section
I was able to get it working by adding the following method to my Application. Note this also opens up the API so that you can accept CrossOrigin requests. The details of the addMapping()
bit are up to you, but this example opens up everything from everywhere. Here is the full class.
@SpringBootApplication
@EnableSwagger2
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
};
}
}
If you are using Spring Security
please add this code.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().configurationSource(request ->
{
CorsConfiguration cors = new CorsConfiguration();
cors.setAllowedMethods(
Arrays.asList(HttpMethod.DELETE.name(),HttpMethod.GET.name(), HttpMethod.POST.name()));
cors.applyPermitDefaultValues();
return cors;
}).httpBasic();
}
Explanation:
In the above CorsConfiguration class I'm using two methods.
cors.applyPermitDefaultValues();
cors.setAllowedMethods(List of Request Type name);
This method cors.applyPermitDefaultValues(); will allow cross origin request for all hosts. Usually this method support cross origin support for these 3 request type methods GET,HEAD and PUT.
If your API exposing PUT , DELETE or any other request methods. Then you need to override it by this cors.setAllowedMethods();