0

I am using springdoc (v1.5.9) to generate Swagger definitions for an API. After authenticating inside the Swagger UI and executing a secured method, the http request received by the Spring Boot app has no Authentication header. I have confirmed via JS debugger that the Swagger UI received and stored a valid authentication token.

Below are the HTTP request, the Swagger api-docs showing the security scheme defined / applied to the method, the springdoc configuration and a controller.

How do I need to change / add to my Spring configuration to get the Authorization passed to the API from the Swagger UI?

HTTP request received

Request received for GET '/foo/1234':
org.apache.catalina.connector.RequestFacade@71c70030

servletPath:/foo/1234
pathInfo:null
headers: 
host: localhost:8070
connection: keep-alive
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
accept: application/json
sec-ch-ua-mobile: ?0
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
referer: http://localhost:8070/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cookie: JSESSIONID=A0F9846102153C06D77D6ED5506CC227
Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  CsrfFilter
  LogoutFilter
  BearerTokenAuthenticationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

api-docs

{
    "openapi": "3.0.1",
    "info": {
        "title": "My App",
        "version": "v1"
    },
    "servers": [
        {
            "url": "http://localhost:8070",
            "description": "Generated server url"
        }
    ],
    "paths": {
        "/foo/{id}": {
            "get": {
                "tags": [
                    "foo"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                },
                "security": [
                    {
                        "custom": [
                        ]
                    }
                ]
            }
        },
        "securitySchemes": {
            "access_token": {
                "type": "oauth2",
                "in": "header",
                "scheme": "custom",
                "flows": {
                    "authorizationCode": {
                        "authorizationUrl": "https://login.myauthsever.com/v2/oauth/authorize",
                        "tokenUrl": "https://login.myauthsever.com/v2/oauth/token",
                        "scopes": {
                        }
                    }
                }
            }
        }
    }
}

OpenAPI config

@OpenAPIDefinition(info = @Info(title = "My App", version = "v1"))
@SecurityScheme(scheme = "custom", type = SecuritySchemeType.OAUTH2, in = SecuritySchemeIn.HEADER, name = "access_token",
        flows = @OAuthFlows(authorizationCode = @OAuthFlow(
                authorizationUrl = "https://login.myauthsever.com/v2/oauth/authorize",
                tokenUrl = "https://login.myauthsever.com/v2/oauth/token", scopes = {})))

public class OpenApiConfig {
}

Controller

@RestController
@Tag(name = "foo")
@SecurityRequirement(name = "custom")
public class SystemSigController {
        @GetMapping(path = "/foo/{id}")
        String getFoo(@PathVariable String id) {
            ...
        }
}
Timothy Vogel
  • 1,363
  • 2
  • 21
  • 39
  • In `@SecurityScheme`, try replacing `type = SecuritySchemeType.OAUTH2` with `type="oauth2"` and also remove the `in` and `name` attributes. Does this help? – Helen Aug 02 '21 at 10:29
  • Thanks for the suggestion. Changing type results in a compile error as type is required to be a ``SecuritySchemeType``. Removing either of the other two results in no Authorization button on the Swagger UI. I missed a section to the api-docs at the bottom in the first posting. I added it to show the details for the security scheme. – Timothy Vogel Aug 02 '21 at 13:02

1 Answers1

2

The @SecurityRequirement.name value must be the same as @SecurityScheme.name.

Since you have @SecurityScheme(..., name = "access_token"...), the controller must use:

@SecurityRequirement(name = "access_token")
Helen
  • 87,344
  • 17
  • 243
  • 314
  • Thank you for sharing your expertise in Swagger to solve my problem! I thought name in ``@SecurityScheme`` was the name of the token in the HTTP header. With all matching the name value it is working as expected. – Timothy Vogel Aug 02 '21 at 13:52