Hi,

I wasn't sure if this was a Spring Boot issue, or SpringDoc issue, hence why I am posting here: This relates to Open-API docs.

These two links DO work:

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

http://localhost:8080/v3/api-docs

http://localhost:8080 (is the direct address access)

My configuration in this resource server is:

# spring doc settings
springdoc:
  api-docs:
    enabled: true
    version: openapi_3_1
    path: /v3/api-docs
  swagger-ui:
    enabled: true
    disable-swagger-default-url: true
    path: /swagger-ui.html
  show-actuator: false
  enable-kotlin: true
  enable-spring-security: true
  enable-default-api-docs: true
  default-produces-media-type: application/json

I also have on this server:

server:
  address: ${LOCALHOST}
  port: ${RESOURCE_SERVER_PORT}
  ssl:
    enabled: true
  forward-headers-strategy: framework

When I try to access this via a reverse proxy & bff, i.e.

http://localhost:7080/viviana/bff/api/v1/resource/swagger-ui.html

I get this:

enter image description here

The swagger GET request, and location are fine:

enter image description here

Everything works, upto the call swagger-config, where I see:

enter image description here

I notice that the GET request is right, but the location just says: http://localhost:7080/viviana/bff

Then after that I get a 404.

I am adding the correct headers in the bff, before the request goes to the resrouce server (port 8080)

// clear all existing X-Forwarded headers
 listOf("X-Forwarded-Host", "X-Forwarded-Proto", "X-Forwarded-Prefix",
   "X-Forwarded-For", "X-Forwarded-Port", "X-Forwarded-Ssl").forEach { header ->
     f.removeRequestHeader(header)}
 // set the ones we need
 f.setRequestHeader("X-Forwarded-Host", serverProperties.clientHost)
 f.setRequestHeader("X-Forwarded-Proto", serverProperties.clientProtocol)
 f.setRequestHeader("X-Forwarded-Prefix", fullClientPathPrefix)

Finally, my gradle settings, in the resource server:

/* spring doc OpenAPI */
implementation("org.springdoc:springdoc-openapi-starter-webflux-api:2.8.11")
implementation("org.springdoc:springdoc-openapi-starter-webflux-ui:2.8.11")

For a get request to the open-apu docs:

   http://localhost:7080/viviana/bff/api/v1/resource/v3/api-docs

In the response header I just get this:

http://localhost:7080/viviana/bff/

Can someone help understand what I'm doing wrong? (this is only a problem when I make a call via the reverse proxy & bff)

Thanks in advance,

Comment From: wilkinsona

I wasn't sure if this was a Spring Boot issue, or SpringDoc issue, hence why I am posting here

Sorry, but that's not how our issue tracking works. We don't have time to diagnose a problem, especially without a sample that reproduces it, that may not even be a Spring Boot problem.

Please take some time to read through https://github.com/spring-projects/spring-boot/wiki/How-To-Get-Help and follow its advice. As it describes, the first steps will help you with your own problem diagnosis. If that doesn't resolve the problem, the next step should be to ask a well-formed question on Stack Overflow that includes the bare minimum required for someone to reproduce the problem. If the problem remains unsolved, only then should you raise an issue hopefully with a good idea of exactly where the bug lies.

Comment From: dreamstar-enterprises

Hi Will,

Thanks for replying.

I have included all the information to re-produce the problem.

And it does exist (as evidenced from the screen-shots)

It is a Spring Boot problem, as it works via one link, but not an other.

That is why I posted in the obvious place, i.e. here.

Thanks again for your patience

Comment From: bclozel

It seems that the problem comes from that HTTP 302 response and "Location" header sent by the application. Spring Boot does not send such a header. Given that there are many moving parts here (a proxy, a "backend for front-end" app, another application using springdoc), I don't thinkyou have narrowed things down enough to qualify as a Spring Boot bug.

You'll have to follow Andy's advice to make progress here.

Comment From: dreamstar-enterprises

Hi Brian,

Thanks for also replying.

I can't say I know the internals of Spring Boot Webflux too deeply, as a kotlin / java developer.

Everything does work fine, when I try accessing those two links directly on the resource server, which makes me think it's some re-direct that is working in Swagger, but not OpenAPI docs, and its interaction with something internal in Spring Boot - despite me adding the X-Forward headers, and activing forward-strategy=native on the resource server

General points and feedback taken, and I've also followed yours and Wills advice to also take this to Stack Overflow: https://stackoverflow.com/questions/79748720/spring-boot-v3-api-docs-swagger-not-working-behind-reverse-proxy

I will circle back, if I manage to track down the root cause.

If you think something else might be going on, would be grateful if you can let me know, so I can further investigate.

KR,

Comment From: bclozel

@dreamstar-enterprises Andy initially pointed to this wiki section as your question as it stands is likely to get closed on StackOverflow. With so much involved and no way to reproduce easily the problem, you're essentially asking people to pair program with you on a particular problem. Reducing the scope or debugging the problem is likely to help you remove the unnecessary bits and get more attention to your question.

Comment From: dreamstar-enterprises

I hope you don't mind me disagreeing, respectfully. (I think it's ok to share the problem on StackOverflow - I don't think it will get closed)

With some further tenacity, and investigation, this IS INDEED a Spring bug / inconsistency...

Image

The path for api-docs, DOES need the prefix, that gets stripped out by the BFF. (there is no documentation that mentions this, if this should be obvious) The path for swagger, DOES NOT (as the internal Spring Boot mechanism that uses the forward header strategy does work)

Re-test results (with that single change): Though even here, some parts of the Filename under Get do look repeated (but it works... - there is no redirect) (in fact any prefix works, like path: /docs/v3/api-docs also works, just this path: /v3/api-docs , doesn't)

Image

Appreciate the Spring team is a hard working team. I do sometimes feel genuine issues are closed a bit too quickly here. I'm guessing this is a library implementation issue (between Spring Boot and SpringDoc)

  /* spring doc OpenAPI */
    implementation("org.springdoc:springdoc-openapi-starter-webflux-api:2.8.11")
    implementation("org.springdoc:springdoc-openapi-starter-webflux-ui:2.8.11")

Anyway, appreciate, you guys not cutting this off completely. and following up with some replies.

I've shared my findings here now. and will also on StackOverflow..

Comment From: bclozel

I hope you don't mind me disagreeing, respectfully. (I think it's ok to share the problem on StackOverflow - I don't think it will get closed)

I meant that questions that lack focus or information tend to get closed on StackOverflow because they are not actionable from a community perspective.

With some further tenacity, and investigation, this IS INDEED a Spring bug / inconsistency...

From what you are describing, I still don't understand what is the actual behavior, the expected one, and how all of those pieces interact together. You seem to casually mention the BFF but I have no idea how it works and how it interacts with the rest. Further refining the problem should definitely help figuring out if it's a documentation issue in Spring Framework about Forwarded requests, an interaction problem between Spring and springdoc, or something else.

Comment From: dreamstar-enterprises

Hi Brian,

It's a configuration issue / inconsistency between Spring Boot and Spring Docs (I believe)

From the work I did, in the resource server (a simple spring app) - the below works:

# spring doc settings
springdoc:
  api-docs:
    enabled: true
    version: openapi_3_1
    path: /docs/v3/api-docs
  swagger-ui:
    enabled: true
    disable-swagger-default-url: true
    path: /swagger-ui.html
  show-actuator: false
  enable-kotlin: true
  enable-spring-security: true
  enable-default-api-docs: true
  default-produces-media-type: application/json

The most confusing part is why the default does not work (where I was stuck all day yesterday)

path: /v3/api-docs does not work, and gives the 302 redirect.

The BFF, is just a router, that uses Spring Cloud Gateway to do the routing, like this:

The recommended Spring approach (from the docs I read) is to add the X-Forwarded headers (like shown below),

``` / Route for the /test/ endpoint, requiring 'ROLE_ADMIN' .route("test-resilience-endpoints") { r -> r.path("${serverProperties.resourceServerPrefix}/test/") .filters { f -> f.stripPrefix(3)

                    val fullClientPathPrefix = (serverProperties.bffServerPrefix?.trimEnd('/') ?: "") +
                            (serverProperties.resourceServerPrefix?.trimEnd('/') ?: "")

                    // clear all existing X-Forwarded headers
                    listOf("X-Forwarded-Host", "X-Forwarded-Proto", "X-Forwarded-Prefix",
                        "X-Forwarded-For", "X-Forwarded-Port", "X-Forwarded-Ssl").forEach { header ->
                        f.removeRequestHeader(header)
                    }
                    // set the ones we need
                    f.setRequestHeader("X-Forwarded-Host", serverProperties.clientHost)
                    f.setRequestHeader("X-Forwarded-Proto", serverProperties.clientProtocol)
                    f.setRequestHeader("X-Forwarded-Prefix", fullClientPathPrefix)

                    // 1. Authenticate with JWT first
                    f.filter(tokenRelayGatewayFilterFactory.apply())

                    // 2. Authorize based on roles (requires 'ROLE_ADMIN')
                 ...

                    // Apply resilience filters as desired for this endpoint
                  .....

                    f.removeRequestHeader("Cookie")
                }
                .uri(serverProperties.resourceServerUri)
        }

And then in the Resource Server, also set the below config (which uses the headers-strategy, to pick up the bff prefixes (that the bff stripped out, when pattern matching paths, but which is adds via the X-Forwarded headers), SO THAT, if the resource server has to generate a redirect URL, it generates the right one


server: address: ${LOCALHOST} port: ${RESOURCE_SERVER_PORT} ssl: enabled: true forward-headers-strategy: native ```

The core issue is still why this doesn't work

path: /v3/api-docs does not work, and gives the 302 redirect.

But my solution is this

path: /docs/v3/api-docs

Recommendation:

  • Work to update the official docs
  • Coodination between Spring Boot / Spring Docs