CORS issue on Swagger UI
Asked Answered
I

6

10

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);
Internal answered 9/9, 2015 at 13:29 Comment(6)
you might want to read more about CORS at enable-cors.org or html5rocks.com/en/tutorials/corsFillender
I am sure your Firefox has a version ? ;-) Please create a network trace using the F-tools of Firefox and show us the headersFillender
So your setup is not causing the correct headers be set. Can you see these headers on the other instance ? Perhaps you set them in the wrong place.Fillender
Unfortunately not, I know a bit about CORS and because of this I tried to get you into the right direction. But I don't know Swagger, so we need someone to read your question which contains more relevant information nowFillender
Try adding OPTIONS to the list of allowed methods. Also, what's the output of curl -I http://127.0.0.1:9000/api-docs/service.json?Seumas
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 428 I tried adding OPTIONS. It dint work eitherInternal
H
4

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.

  1. cors.applyPermitDefaultValues();

  2. 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();

Humfried answered 13/4, 2019 at 14:38 Comment(4)
Please elaborate your code by adding an explanation or comments (in your code).Pothook
@Pothook Can you please check now, whether this is enough..?Humfried
Yea, that looks much better. Note that you can also write keywords like functions in code by putting them between ``. For example, it will look like cors.applyPermitDefaultValues();.Pothook
@Pothook Thanks..!! I'm newbie to stack overflow. This will help me.Humfried
S
3

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

Subdominant answered 6/4, 2016 at 13:55 Comment(1)
Mine turned out to be a corrupt JSON file, I am using eve-swagger and instead of using the default /api-docs JSON file I used a test one which had extra characters in it. Thanks for the info!Monahan
M
2

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("*");
      }
    };
  }
}
Monostich answered 10/5, 2018 at 19:48 Comment(0)
C
1

For Springdoc OpenAPI the following fix the issue: @OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")})

Clarabelle answered 17/1, 2022 at 19:22 Comment(1)
It worked for me, but I didn't use the annotations. I added that in a config file : return new OpenAPI().servers(Collections.singletonList(new Server().url("/").description("Default server url")))Hardecanute
G
0

I have just encounter what way be a similar problem: Swagger UI: HTTP Content-type "application/json" causes "Unable to Load SwaggerUI".

Try changing the HTTP Content-type header of your GET service.json response from "application/json" to "text/html", or even removing it. I don't know why, but it seems it makes a difference for Swagger UI.

Gingergingerbread answered 30/3, 2016 at 9:50 Comment(1)
Changing Content-type header didn't solve the issue. Can you please share what specific Swagger editor are you referring to?Unstrap
C
-1

I also had this issue and after inspecting the headers in the pet-store example, I found that "Access-Control-Allow-Headers" needs "Content-Type, api_key, Authorization".

Make sure that you have api_key as well as I had that missing.

Chelsiechelsy answered 26/10, 2018 at 6:21 Comment(1)
How did you add api_key in the header, can you please provide sample code snippet?Beefwitted

© 2022 - 2024 — McMap. All rights reserved.