Spring Boot集成Swagger V3 UI调试时未携带Authorization Header问题
问题描述
使用Spring Boot 2.7.10版本,引入springdoc-openapi-ui 1.6.15依赖,控制器已添加Swagger相关注解,Swagger UI展示正常,但调试需要Authorization请求头的/userinfo接口时,Swagger UI并未在请求中携带该头信息,导致返回400 Bad Request错误,错误信息如下:
org.springframework.web.bind.MissingRequestHeaderException: Required request header 'Authorization' for method parameter type String is not present
控制器代码
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Contact; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.security.SecurityScheme; import io.swagger.v3.oas.annotations.servers.Server; import io.swagger.v3.oas.annotations.tags.Tag; /** * This controller will be invoked from the front end to be able to interact * with the IAM Service<br> * For some reason the swagger UI will not work with the getUserInfo request as its not passing in the Authorization header * * @author Hanif Rajabali */ @OpenAPIDefinition( info = @Info( title = "${api.info.title}", version = "${api.info.version}", description = "${api.info.description}", termsOfService = "${api.info.termsOfService}", contact = @Contact(name = "${api.info.contact.name}", url = "${api.info.contact.url}", email = "${api.info.contact.email}") ), servers = { @Server(description = "${api.server.description}", url = "${api.server.url}") }) @SecurityScheme(name = "JWT Access Token", type = SecuritySchemeType.HTTP, scheme = "bearer", bearerFormat = "JWT", in = SecuritySchemeIn.HEADER) @SecurityRequirement(name = "bearerAuth") @Tag(name = "${api.tag.name}", description = "${api.tag.description}") @CrossOrigin @RestController @RequestMapping(value = "${api.base-request-mapping}", produces = MediaType.APPLICATION_JSON_VALUE) public class LoginController { final Logger log = LoggerFactory.getLogger(this.getClass()); @Autowired private LoginService loginService; @Operation( summary = "Retrieves User Attributes From an Authenticated User Within the IAM User Repository", description = "The userInfo endpoint is an OpenID Connect (OIDC) userInfo endpoint. It responds with user attributes given an access tokens that the Token endpoint issued. The scopes in the users access token define the user attributes that the userInfo endpoint returns in its response. The openid scope must be one of the access token claims. Currently the authentication service provider is AWS Cognito", security = @SecurityRequirement(name = "bearerAuth"), parameters = @Parameter( in = ParameterIn.HEADER, name = "Authorization", description = "Access Token", required = true, schema = @Schema(type = "string", format = "JWT"), example = "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" ) ) @ApiResponses( value = { @ApiResponse(responseCode = "200", description = "Successful Retrieval of User Attributes"), @ApiResponse( responseCode = "401", description = "Unauthorized or Invalid Token", content = { @Content(schema = @Schema(implementation = ApiErrorResponse.class)) }), @ApiResponse( responseCode = "500", description = "Internal Server Error", content = { @Content(schema = @Schema(implementation = ApiErrorResponse.class)) }) }) @GetMapping("/userinfo") @ResponseBody public ResponseEntity<LoginApiResponse<UserInfo>> getUserInfo( @Parameter(in = ParameterIn.HEADER, name = "Authorization", required = true, schema = @Schema(type = "string", format = "Bearer")) @RequestHeader(name = "Authorization", required = true) String accessToken) throws Exception { UserInfo userInfo = this.loginService.getUserInfo(accessToken); LoginApiResponse<?> apiResponse = this.loginService.createApiResponse(userInfo); LoginApiResponse<UserInfo> userInfoResponse = (LoginApiResponse<UserInfo>) apiResponse; return ResponseEntity.ok(userInfoResponse); } }
Swagger UI截图

解决方案
问题根源在于安全方案的名称不匹配:
- 你定义的
@SecurityScheme的name是"JWT Access Token",但类上和方法上的@SecurityRequirement引用的name是"bearerAuth",两者不一致导致Swagger UI无法识别对应的授权配置,因此不会自动携带Authorization请求头。
修复步骤:
- 统一安全方案名称,将
@SecurityScheme的name修改为"bearerAuth",与@SecurityRequirement保持一致:@SecurityScheme(name = "bearerAuth", type = SecuritySchemeType.HTTP, scheme = "bearer", bearerFormat = "JWT", in = SecuritySchemeIn.HEADER) - (可选)方法上的
@Parameter注解可以保留,但其实通过SecurityScheme已经能定义Authorization头,保留的话不影响功能。
修改后,Swagger UI会显示Authorize按钮,点击后输入Bearer格式的token,后续请求就会自动携带Authorization头,解决400错误。
内容的提问来源于stack exchange,提问作者ustad
相关产品推荐
相关产品推荐

