'Springfox swagger-ui.html unable to infer base URL - Caused by missing cookies
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:
- https://base_address/base_context/swagger-resources/configuration/ui
- https://base_address/base_context/swagger-resources/configuration/security
- https://base_address/base_context/swagger-resources
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.
Solution 1:[1]
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);
}
Solution 2:[2]
Adding below annotation at the spring boot class resolved this issue for me.
@EnableSwagger2
I am using swagger version
<version>2.9.2</version>
Solution 3:[3]
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");
}
}
Solution 4:[4]
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
Solution 5:[5]
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.
Solution 6:[6]
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());
Solution 7:[7]
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);
}
}
Solution 8:[8]
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.
Solution 9:[9]
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);
}
}
Solution 10:[10]
In many cases it is due to Java Version incompatibility. Many times it doesn't work with Java 11
, try using Java 8
Solution 11:[11]
try with port 8080 - worked for me after i changed it to 8080
Solution 12:[12]
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);
}
}
Solution 13:[13]
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.
Solution 14:[14]
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>
Solution 15:[15]
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
Solution 16:[16]
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>
Solution 17:[17]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow