50

We have our Spring Boot services behind an API Gateway. With an earlier version of Springfox - 2.1.2 we had no issues in loading the swagger-ui.html page. This worked with Spring Boot 1.4.3.RELEASE. From then, we have upgraded to Boot 1.5.7 and upgraded Springfox to 2.8.0.

Now if we load the page we get an alert box with the following long message.

Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway. The base url is the root of where all the swagger resources are served. For e.g. if the api is available at http://example.org/api/v2/api-docs then the base url is http://example.org/api/. Please enter the location manually

I got some hints searching online, but it does not seem those situations apply to us. For one, if I simply revert back the versions, it starts working again through the same API Gateway.

Tracking the traffic, it seems calls to three XHR resources made by the .html page is causing issues. These are returning 401 from our API gateway. And the reason they return 401 is because the cookies are not passed along.

The three calls are:

If I load these URLs as pure browser requests - they work - because cookies are sent.

I doubt if CORS applies since the HTML is being served from the same address as the swagger JSON and actual service calls.

Any idea why this may be happening? Anybody faced similar issues? Suggestions for workaround? Thanks much in advance.

Pavindu
  • 2,684
  • 6
  • 44
  • 77
Arnab Gupta
  • 677
  • 1
  • 5
  • 9

25 Answers25

33

Add in the security config -- following URLS that are skipped for authentication ::

private static final String[] AUTH_WHITELIST = {
        "/swagger-resources/**",
        "/swagger-ui.html",
        "/v2/api-docs",
        "/webjars/**"
};

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(AUTH_WHITELIST);
}
panksy2k
  • 401
  • 5
  • 3
  • 1
    FWIW This worked for SpringFox 3.0 for me. I added /swagger-ui/** since, at least for me, the URL is /swagger-ui/index.html. Didn't seem to need the webjars path, but I might have just not hit that yet. – David Bradley May 04 '22 at 15:36
27

Adding below annotation at the spring boot class resolved this issue for me.

@EnableSwagger2

I am using swagger version

 <version>2.9.2</version>
Arindam
  • 675
  • 8
  • 15
8

SEE EDIT BELOW

Do you use spring security?

If yes, probably you skip some resources like this (right?): "/swagger-resources/**", "/swagger-ui.html", "/v2/api-docs", "/webjars/**"

Try to change it "/swagger-resources/**" to "**/swagger-resources/**".

My specific security config for swagger is:

private static final String[] AUTH_LIST = {
        // -- swagger ui
        "**/swagger-resources/**",
        "/swagger-ui.html",
        "/v2/api-docs",
        "/webjars/**"
};

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    .authorizeRequests().antMatchers(AUTH_LIST).authenticated()
    .and()
    .httpBasic().authenticationEntryPoint(swaggerAuthenticationEntryPoint())
    .and()
    .csrf().disable();
}

@Bean
public BasicAuthenticationEntryPoint swaggerAuthenticationEntryPoint() {
    BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
    entryPoint.setRealmName("Swagger Realm");
    return entryPoint;
}

If you need/want I can send a sample project to GitHub to you know more about my security/swagger configs.

EDIT 2018/04/10

This problem is caused by a wrong version in springfox. See this issue on github to solve the problem.

To posterity:

In pom.xml

...
<repositories>
    <repository>
        <id>swagger</id>
        <name>swagger</name>
        <url>http://oss.jfrog.org/artifactory/oss-snapshot-local</url>
    </repository>
</repositories>
...
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.1-SNAPSHOT</version>
</dependency>
...

Class that extends WebSecurityConfigAdapter:

@Configuration
public class WebSecurityConfigEntryPointApplication extends WebSecurityConfigurerAdapter {

    private static final List<String> AUTH_LIST = Arrays.asList(
            "/swagger-resources/**",
            "/swagger-ui.html**",
            "/webjars/**",
            "favicon.ico");

    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .antMatcher("/**").authorizeRequests().anyRequest().authenticated()
                .and()
                .exceptionHandling()
                .defaultAuthenticationEntryPointFor(swaggerAuthenticationEntryPoint(), new CustomRequestMatcher(AUTH_LIST))
                .and()
                .httpBasic()
                .authenticationEntryPoint(restAuthenticationEntryPoint)
                .and()
                .csrf().disable();
    }

    @Bean
    public BasicAuthenticationEntryPoint swaggerAuthenticationEntryPoint() {
        BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
        entryPoint.setRealmName("Swagger Realm");
        return entryPoint;
    }

    private class CustomRequestMatcher implements RequestMatcher {

        private List<AntPathRequestMatcher> matchers;

        private CustomRequestMatcher(List<String> matchers) {
            this.matchers = matchers.stream().map(AntPathRequestMatcher::new).collect(Collectors.toList());
        }

        @Override
        public boolean matches(HttpServletRequest request) {
            return matchers.stream().anyMatch(a -> a.matches(request));
        }

    }

}

RestAuthenticationEntryPoint:

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}
Marco Blos
  • 933
  • 9
  • 22
  • I have these set up. The issue is actually with 2.8.0 itself. I filed issue here: https://github.com/springfox/springfox/issues/2281 – Arnab Gupta Apr 09 '18 at 22:39
  • Hi @ArnabGupta. You are right! I made one comment on github with all steps to solve this problem. You get it here: https://github.com/springfox/springfox/issues/2191 – Marco Blos Apr 10 '18 at 13:00
7

This happened to me, I was using SpringBoot 1.5.16 and Springfox 2.9.1.

In my application.properties, I had defined server.servlet-path=/api, but, somehow, the swagger-ui was ignoring the value defined. I've tried so many different way to make this work, and finally I found a workaround:

 @Configuration
 @EnableSwagger2
 public class SwaggerConfiguration extends WebMvcConfigurationSupport {                                    

    @Bean
    public Docket apiMonitoramento() { 
        return new Docket(DocumentationType.SWAGGER_2)
                .select()                                  
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())                          
                .build()    
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()              
                .title("REST API")
                .description("Servicesx")               
                .build();
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
 }

I was accessing http://localhost:8080/context/swagger-ui.html, but with that configuration the correct URL is: http://localhost:8080/context/api/swagger-ui.html

carolnogueira
  • 499
  • 5
  • 10
3

In my case, the cause of the problem was having:

@ComponentScan(basePackageClasses = {ApplicationRoot.class })

twice in two java files.

after removing the extra one, the problem went away.

SHR
  • 7,940
  • 9
  • 38
  • 57
Guram Kankava
  • 51
  • 1
  • 4
2

Upgrade springfox-swagger2 and springfox-swagger-ui dependencies to 2.9.2 and also ensure the basePackage is given properly

return new Docket(DocumentationType.SWAGGER_2).select()
            .apis(RequestHandlerSelectors
                .basePackage("org.abc.xyz.controller"))
            .paths(PathSelectors.regex("/.*"))
            .build().apiInfo(apiEndPointsInfo());
2

I don't use spring security happened this question. My Project Use Maven Multiple Module, When access to the localhost:8080/swagger-ui.html happend this question, First I add @EnableSwagger2 in the SwaggerConf class ,Last I move @EnableSwagger to SpringBoot Application class ,this question is solved. First:

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.zuoyan."))
                .paths(PathSelectors.any())
                .build();
    }

}

Finally:

 @SpringBootApplication(scanBasePackages = {"com.zuoyan.springboot.appmissionhall"})
 @EnableSwagger2
public class ApplicationStartUpApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationStartUpApplication.class, args);
    }

}
Zuoyan
  • 21
  • 1
2

Just clear your browser cache. It worked for me.

My Swagger Docket Bean Config file:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class DocketBean implements WebMvcConfigurer {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.swagger.demo"))
                .paths(PathSelectors.any())
                .build();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        
        // enabling swagger-ui part for visual documentation
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

Swagger Dependencies in POM:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

The swagger-ui url :

http://localhost:8080/swagger-ui.html

1

If you do not specify any special component scan options you will face this problem if you put the class with the @EnableSwagger2 annotation in a package that is not in the hierarchy of your Spring Boot Application class (@SpringBootApplication).

Assume your Spring Boot Application class in "de.oopexpert.app", then putting @EnableSwagger2 annotated class in ...

  • de.oopexpert.app will work
  • de.oopexpert.app.config will work
  • de.oopexpert.config will NOT work

You may adapt your component scan options by adding @ComponentScan(basePackages = {"de.oopexpert"}) to specify a different root of the hierarchy.

oopexpert
  • 767
  • 7
  • 12
1

The solution from https://stackoverflow.com/a/56716898/13347514 by adding @EnableSwagger2WebMvc and @Import(SpringDataRestConfiguration.class) to the Main Application Class fixes my problem:

@SpringBootApplication
@EnableSwagger2WebMvc
@Import(SpringDataRestConfiguration.class)
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}
bdk
  • 11
  • 2
1

In many cases it is due to Java Version incompatibility. Many times it doesn't work with Java 11, try using Java 8

Cyber
  • 2,194
  • 4
  • 22
  • 41
0

try with port 8080 - worked for me after i changed it to 8080

Pravin Bansal
  • 4,315
  • 1
  • 28
  • 19
0

I added @EnableSwagger2WebMvc to the App class to fix it. I am using Spring boot 2.3.0.BUILD-SNAPSHOT and io.springfox 3.0.0-SNAPSHOT. SpringFoxConfig class stays the same.

package com.telixia.educare.academy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

@EnableSwagger2WebMvc
@SpringBootApplication
public class AcademyApplication {

    public static void main(String[] args) {
        SpringApplication.run(AcademyApplication.class, args);
    }

}
Nditah
  • 1,429
  • 19
  • 23
0

This could also be caused by the springfox-swagger-ui and springfox-swagger2 versions mismatch in the pom.xml, for example, if you updated one but forgot to update another:

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger2</artifactId>
  <version>2.6.1</version>
</dependency>
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger-ui</artifactId>
  <version>2.9.2</version>
</dependency>

You need to make sure springfox-swagger-ui and springfox-swagger2 have the same version.

Kirill Simonov
  • 8,257
  • 3
  • 18
  • 42
0

Firstly make sure these 2 dependencies are added and then annotate your main SpringBootApplication class with @EnableSwagger2 and then your problem will be solved.

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>

Screen shot of main SpringBootApplication class

Aashman Thing
  • 302
  • 2
  • 6
0

I was facing the same issue with a basic Spring MVC application (no Spring Security).

I replaced

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.
        addResourceHandler("/swagger-ui/**")
        .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
        .resourceChain(false);
  }

with

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.
        addResourceHandler("/swagger-ui/**")
        .addResourceLocations("classpath:/META-INF/resources/");
            registry.addResourceHandler("**/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");

  }

and it did the trick

mnagdev
  • 384
  • 3
  • 11
0

In my case, adding the springfox-spring-webmvc dependency resolved the issue:

   <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spring-webmvc</artifactId>
            <version>2.10.5</version>
        </dependency>
0xadecimal
  • 696
  • 5
  • 18
0

I had the same problem, but just adding @EnableSwagger2 on top of the main App class fixed it.

example :

    @SpringBootApplication
    @EnableSwagger2
    public class AcademyApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(AcademyApplication.class, args);
        }
    
        @Configuration
        class RestTemplateConfig {
            @Bean
            @LoadBalanced
            public RestTemplate restTemplate() {
                return new RestTemplate();
            }
        }
    
    }
0

I had the same issue,i had written @EnableSwagger2 annotation at class level in SwaggerConfig file but i forgot to place @Configuration at class level in SwaggerConfig class. Adding that annotation solved my issue.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@EnableSwagger2
@Configuration
public class swaggerConfig {

// swagger configuration
    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2).select()
                .apis(RequestHandlerSelectors.basePackage("mention your package name here")).build();
    }
}

If you have the same issue again then do @ComponentScan(basePackages = "mention your root package name here") in your Application.java file

Dr4kk0nnys
  • 697
  • 7
  • 13
0

In my case, My project use Maven multiple module without spring security.

  • SpringBoot v2.2.7.RELEASE
  • Swagger2 & Swagger-ui v2.9.2

My solution is change the value of @Profile(), enter the right name of the configuration profile you create in the project resourse directory.

First:

@Configuration
@EnableSwagger2
@Profile({ "dev", "test" })
public class SwaggerConfig {

 private ApiInfo getApiInfo(String title, String desc) {
        return new ApiInfoBuilder().title(title) 
                .description(desc) 
                .version(DOC_VERSION) 
                .termsOfServiceUrl(URL)                         
                .build();
    }

}

Last:

@Configuration
@EnableSwagger2
// @Profile({ "dev", "test" })
@Profile({ "kf-oracle", "kf-mysql" })
public class SwaggerConfig {

 private ApiInfo getApiInfo(String title, String desc) {
        return new ApiInfoBuilder().title(title) 
                .description(desc) 
                .version(DOC_VERSION) 
                .termsOfServiceUrl(URL)                         
                .build();
    }

}
Mr.Yao
  • 1
0

First, add the Swagger dependency to pom.xml

Swagger Dependency in POM

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>


    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>

After that, it's time to configure the Swagger 3rd party that we installed. Therefore follow the order below.

1/Make a package and set name Config
2/Make a class SwaggerConfig
3/After it set below code to that class

@Configuration
public class SwaggerConfig {

@Bean
public Docket SwaggerApi(){
    return  new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build();
}

}

4/checked that class @Configuration and @Bean annotations
5/Need to enable Swagger2 in your main method class
6/use @EnableSwagger2 annotation to Enable Swagger 2
After that go to your browser and get swagger UI to see our UI. For it use this code http://localhost:8081/swagger-ui.html#/ check your server.port

If any doubt coming cheng your spring-boot-starter-parent pom.xml to low version.

Example:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.4</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

your project will run without error and smoothly.

Procrastinator
  • 2,526
  • 30
  • 27
  • 36
0

Try the following in "*.yml" file

swagger:
  enable: true

or try "swagger.enable=true" in "*.properties"

0

hi i found solution for this swagger popup as we can see a input box inside a swagger you need to add /web or what ever url pattern configured in your code example in popup input text field you need to add like this
popup with error

solution

  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/33705336) – biasedbit Jan 30 '23 at 02:35
0

I'm using swagger version 2.9.2 just added @EnableSwagger2 and the error was gone and I was able to access the UI

0

Late to the party, but I thought I'd add my cause of & fix for the springfox "unable to infer base-url" error.

In my case I copied another project to work on some test code. This project had this code: dispatcher.addMapping("/myapi/*");. That was the code causing the issue. I think this caused springfox to look on the wrong url for the data. I just made this a "/" & springfox worked correctly.

I forget why I'd defined it like that in the other project.

//original code
    ServletRegistration.Dynamic dispatcher = container.addServlet("MY-dispatcher", new DispatcherServlet(context));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/myapi/*");
    
    
//updated code    
    ServletRegistration.Dynamic dispatcher = container.addServlet("MY-dispatcher", new DispatcherServlet(context));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");
Mr Smith
  • 3,318
  • 9
  • 47
  • 85