spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.57k stars 40.55k forks source link

Spring Boot (Webflux) - Swagger UI - redirect URI does not include Gateway Prefix #42305

Closed dreamstar-enterprises closed 1 week ago

dreamstar-enterprises commented 1 week ago

My settings:

# spring doc settings
springdoc:
  api-docs:
    enabled: true
    version: openapi_3_1
    path: /v3/api-docs
  swagger-ui:
    enabled: true
    path: /v1/swagger-ui.html
    url: /v3/api-docs
    operations-sorter: method

# default server settings
server:
  address: ${LOCALHOST}
  port: ${RESOURCE_SERVER_PORT}
  ssl:
    enabled: false
  forward-headers-strategy: native (here framework doesn't work for me - I keep getting 403 Forbidden)
# default spring settings
spring:
  # application settings
  application:
    name: Timesheets-RESTApiApplication
  # profile settings
  profiles:
    active: dev
  # lifecycle settings
  lifecycle:
    timeout-per-shutdown-phase: ${TIMEOUT_SHUTDOWN}
  # main settings
  main:
    allow-bean-definition-overriding: true
  # webflux settings
  webflux:
    base-path: ${RESOURCE_SERVER_PREFIX}

What happens:

My Swagger link works:

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

But it forwards to:

location:

/api/v1/resource/webjars/swagger-ui/index.html

which goes to

http://localhost:7080/api/v1/resource/webjars/swagger-ui/index.html

(as it misses /bff, I keep getting back 404 Not Found)

I can see my BFF forwarding the right headers in the request to the Resource Server:

Forwarded: proto=http;host="localhost:7080";for="127.0.0.1:51801"
X-Forwarded-For: 127.0.0.1
X-Forwarded-Proto: http
X-Forwarded-Prefix: /bff
X-Forwarded-Port: 7080
X-Forwarded-Host: localhost:7080
host: localhost:9090
content-length: 0
Authorization: Bearer eyJhb...

I've looked at the Spring Boot Swagger Code too

@Controller
public class SwaggerWelcomeWebFlux

    protected String buildUrlWithContextPath(String swaggerUiUrl) {
        if (this.pathPrefix == null) {
            this.pathPrefix = this.springWebProvider.findPathPrefix(this.springDocConfigProperties);
        }

        return this.buildUrl(this.contextPath + this.pathPrefix, swaggerUiUrl);
    }

This seems to ignore any Gateway prefix that might be in X-Forwarded-Prefix enabled by forward-headers-strategy: native

This looks like a bug to me.

wilkinsona commented 1 week ago

Spring Docs, which includes theSwaggerWelcomeWebFlux class you've posted above, isn't part of Spring Boot. I think you should report this to https://github.com/springdoc/springdoc-openapi where SwaggerWelcomeWebFlux is maintained.

dreamstar-enterprises commented 6 days ago

I'm inclined to disagree, and feel this is more of a Spring Boot framework issue Whichever internal library generates a redirect URL, (SpringDoc or Spring Security, etc) The gateway prefix should be added by the base framework, especially with these base framework settings:

# default spring settings
spring:
  # application settings
  application:
    name: Timesheets-RESTApiApplication
  # profile settings
  profiles:
    active: dev
  # lifecycle settings
  lifecycle:
    timeout-per-shutdown-phase: ${TIMEOUT_SHUTDOWN}
  # main settings
  main:
    allow-bean-definition-overriding: true
  # webflux settings
  webflux:
    base-path: ${RESOURCE_SERVER_PREFIX}
# default server settings
server:
  address: ${LOCALHOST}
  port: ${RESOURCE_SERVER_PORT}
  ssl:
    enabled: false
  forward-headers-strategy: native (here framework doesn't work for me - I keep getting 403 Forbidden)
bclozel commented 6 days ago

Please don't create duplicates. If you think this is a Spring Boot issue, why create https://github.com/springdoc/springdoc-openapi/issues/2708 in the first place?

Let's give the springdoc team some time to assess this and we can reconsider this as a Spring Framework issue later.

dreamstar-enterprises commented 6 days ago

Yes, agreed. I only posted there, after Wilkinson's comment. But on reflection, I think this is a Spring Boot framework issue - as the settings are set in Spring Boot, and that should intercept any redirect url (created by which ever library) and prefix the gateway prefix, from the X-Forwarded-Prefix header, via the setting:

server:
  address: ${LOCALHOST}
  port: ${RESOURCE_SERVER_PORT}
  ssl:
    enabled: false
  forward-headers-strategy: native 
dreamstar-enterprises commented 5 days ago

As requested, I've added a minimum reproduceable example confirming the issue.

Please see - https://github.com/spring-projects/spring-boot/issues/42317