Richard
Richard

Reputation: 8935

java Spring Boot with Swagger - Failed to load remote configuration

I have a Java 11 Spring Boot 2.5.1 application.

Swagger works locally via http:

I have added Swagger, which works perfectly on my localhost:

http://localhost:8085/swagger-ui/index.html#/

enter image description here

Swagger does not work remotely via https:

However, when I deploy it to a remote server, I get the following error:

https://mycompany.co/pow-wow/swagger-ui/index.html#/

enter image description here

Error

Failed to load remote configuration.

note: the remote server is accessed via https.

The REST endpoints are accessible on the remote server.

e.g. GET https://mycompany.co/pow-wow/powwow/test-me returns a 200 as expected.

Question

How do I access the Swagger via the remote server?

Code

pom.xml

    <!-- Swagger -->
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-ui</artifactId>
        <version>1.6.7</version>
    </dependency>

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //http.csrf().disable().authorizeRequests().antMatchers("/powwow/*").hasRole("USER").and().httpBasic();
        //http.csrf().disable().authorizeRequests().antMatchers("/*").permitAll().and().httpBasic();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests().antMatchers("/soapWS/**").permitAll().and()
                .authorizeRequests().antMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll().and()
                .authorizeRequests().antMatchers("/actuator/**").permitAll()
                .anyRequest().authenticated().and()
                .httpBasic().and()
                .csrf().disable();
    }
}

More info:

When looking at the network traffic in the browser when accessing Swagger.

Locally, there is a call to:

http://localhost:8085/v3/api-docs/swagger-config

returns:

enter image description here

{"configUrl":"/v3/api-docs/swagger-config","oauth2RedirectUrl":"http://localhost:8085/swagger-ui/oauth2-redirect.html","url":"/v3/api-docs","validatorUrl":""}

Remotely, there is a call to:

https://mycompany.co/v3/api-docs/swagger-config

which returns a 302.

enter image description here

But https://mycompany.co/pow-wow/v3/api-docs/swagger-config

returns:

{"configUrl":"/v3/api-docs/swagger-config","oauth2RedirectUrl":"http://localhost:8085/swagger-ui/oauth2-redirect.html","url":"/v3/api-docs","validatorUrl":""}

So this suggests the issue is related to the /pow-wow context path is missing in the call.

Upvotes: 7

Views: 19644

Answers (8)

Ashish Singh
Ashish Singh

Reputation: 479

Few points for those who are working in Spring webflux.

  1. You can use the openAPI dependency shared below. No other dependency is needed for this.
org.springdoc springdoc-openapi-starter-webflux-ui 2.3.0
  1. I found out that the path under api-docs field should end with .yaml extension . Otherwise the swagger ui won't come up.
  2. If you're running it in local, you only need below config and the @OpenAPIDefinition annotation in the main class and it will be able to pick all the Controllers. But it won't pick the Functional endpoints(Just FYI. For that you need to manually write API docs definition under annotation @RouterOperations. I will share a link where it is explained easily and beautifully).
springdoc:
  api-docs:
    path: /swagger-doc/v3/api-docs.yaml
    groups:
      enabled: true
  swagger-ui:
    path: /swagger-doc/swagger-ui.html
  1. If you want to put it in higher env, you should add config-url and url fields as well under swagger-ui field. The config is provided below.
springdoc:
  api-docs:
    path: /swagger-doc/v3/api-docs.yaml
    groups:
      enabled: true
  swagger-ui:
    config-url: /<something-AFTER-hostname>/<application-context-path>/swagger-doc/v3/api-docs.yaml/swagger-config
    url: /<something-AFTER-hostname>/<application-context-path>/swagger-doc/v3/api-docs.yaml
    path: /swagger-doc/swagger-ui.html

For example, say your higher env url is like https://host.company.com/customerhelp/helpdesk/api_v1 where https://host.company.com/customerhelp portion is attached by the company infra(may be when Kubernetes is used to deploy services), /helpdesk is the application context path and /api_v1 is an api endpoint.

The config-url will become like:

/customerhelp/helpdesk/swagger-doc/v3/api-docs.yaml/swagger-config

And url will become:

/customerhelp/helpdesk/swagger-doc/v3/api-docs.yaml

Here's the YT link that helped me understanding how to write apiDocs for Functional endpoints. https://www.youtube.com/watch?v=bEtgsJETiTQ&lc=Ugx1wMzR31ESKXeOnMt4AaABAg.A-Tn0aUYQM9A-Tpo1k6SwT

Upvotes: 0

Parag Kadam
Parag Kadam

Reputation: 3850

I was facing the same issue and managed to solve it.

If you have configured your spring security with .authorizeRequests().antMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll() and still get this error then it means that the URL - /swagger-ui/index.html#/ is accessible but the network calls that are made on that page are probably being blocked by spring security. Check the network tab in the browser and make sure all the networks calls are permitted without authentication.

Generally, .authorizeRequests().antMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll() is sufficient but in my case I had path prefix set to api/v1 hence I modified my code to .authorizeRequests().antMatchers("/swagger-ui/**", "/api/v1/v3/api-docs/**").permitAll() to make it work.

Upvotes: 0

Christopher
Christopher

Reputation: 1

Config that helped me:

springdoc:
    swagger-ui:
        configUrl: /your-service/v3/api-docs/swagger-config
        url: /your-service/v3/api-docs

If you have problems with the try it out block (404 error, wrong url), then just use the @OpenAPIDefinition annotation. Kotlin example:

@SpringBootApplication
@OpenAPIDefinition(
    info = Info(title = "Your Service API", version = "1.0", description = "Your service description"),
    servers = [Server(url = "/your-service", description = "Your Service")]
)

Upvotes: 0

Oleg Khilko
Oleg Khilko

Reputation: 1

To those who are asking:

I had the same issue and this video helped me check it out: https://www.youtube.com/watch?v=A_RWUcTqHBI

Just simple step by step.

Regarding my project to be on the same page:

Spring Boot 3 + Spring Security.

So I:

  1. Added "/swagger-ui/" and "/v3/api-docs/" as @Mohamed suggested to my SecurityFilterChain bean.
  2. Added springdoc-openapi-starter-webmvc-ui dependency in POM.
  3. Configurated SwaggerConfig as follow:
@Configuration
@OpenAPIDefinition
public class SwaggerConfig {
    
    @Bean
    public OpenAPI config() {
        return new OpenAPI().info(
                new Info()
                        .title("")
                        .version("")
                        .description("")
        );
    }
}

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

And it worked smoothly!

Upvotes: 0

Ivan dal Bosco
Ivan dal Bosco

Reputation: 3549

I had the same issue :

  • with mvn spring-boot:run : OK
  • on my local Tomcat server : OK
  • on the Tomcat server of my organization : KO (Failed to load remote configuration)

The cause was the reverse proxy of my organization that blocked the loop-back call of the application.

Upvotes: 0

Tohid Makari
Tohid Makari

Reputation: 2484

If security config allow swagger, it's because of cashing, try it after clear browser cash or in browser incognito mode.

Upvotes: 0

GJohannes
GJohannes

Reputation: 1763

You should try and add

springdoc:
  swagger-ui:
    config-url: /pow-wow/v3/api-docs/swagger-config
    url: /v3/api-docs

to your application.properties. In your provided example

https://mycompany.co/pow-wow/v3/api-docs/swagger-config

it shows that you have "/pow-wow/" in your path. Swagger needs to know where to fetch its config.

Upvotes: 9

Mohamed Sweelam
Mohamed Sweelam

Reputation: 1229

Try to add this as well to your security config class

@Override
public void configure(WebSecurity web) throws Exception {
   web.ignoring().antMatchers("/swagger-ui/**", "/v3/api-docs/**");
}

Upvotes: 3

Related Questions