Spring boot + Swagger UI 如何告诉端点需要承载令牌
Spring boot + Swagger UI how to tell endpoint to require bearer token
我正在使用 Spring Boot to build a REST API。我添加了 Swagger-ui 来处理文档。我在实现客户端身份验证流程时遇到了问题,问题是我可以通过基本身份验证获得 swagger-ui 来授权提供的 client-id(username) 和 client-secret(password),但是 swagger UI 似乎没有应用到端点调用的结果访问令牌。
确认一下,我的授权流程;
- 使用基本身份验证将 base64 编码的 username/password & grant_type=client_credentials 发送到 /oauth/token。 Spring returns 一个 access_token
- 在以后的 API 调用中,使用提供的 access_token 作为承载令牌
我认为问题可能是因为我需要在我的控制器中的每个方法上放置一些东西来告诉 swagger 端点 requires 身份验证和什么类型,但我找不到任何明确的有关如何执行此操作的文档,我不知道是否需要对我的 swagger 配置应用任何进一步的更改。
这是一个控制器示例(删除了大多数方法以减小大小);
@Api(value="Currencies", description="Retrieve, create, update and delete currencies", tags = "Currencies")
@RestController
@RequestMapping("/currency")
public class CurrencyController {
private CurrencyService currencyService;
public CurrencyController(@Autowired CurrencyService currencyService) {
this.currencyService = currencyService;
}
/**
* Deletes the requested currency
* @param currencyId the Id of the currency to delete
* @return 200 OK if delete successful
*/
@ApiOperation(value = "Deletes a currency item", response = ResponseEntity.class)
@RequestMapping(value="/{currencyId}", method=RequestMethod.DELETE)
public ResponseEntity<?> deleteCurrency(@PathVariable("currencyId") Long currencyId) {
try {
currencyService.deleteCurrencyById(currencyId);
} catch (EntityNotFoundException e) {
return new ErrorResponse("Unable to delete, currency with Id " + currencyId + " not found!").response(HttpStatus.NOT_FOUND);
}
return new ResponseEntity(HttpStatus.OK);
}
/**
* Returns a single currency by it's Id
* @param currencyId the currency Id to return
* @return the found currency item or an error
*/
@ApiOperation(value = "Returns a currency item", response = CurrencyResponse.class)
@RequestMapping(value="/{currencyId}", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<RestResponse> getCurrency(@PathVariable("currencyId") Long currencyId) {
Currency currency = null;
try {
currency = currencyService.findById(currencyId);
} catch (EntityNotFoundException e) {
return new ErrorResponse("Currency with Id " + currencyId + " could not be found!").response(HttpStatus.NOT_FOUND);
}
return new CurrencyResponse(currency).response(HttpStatus.OK);
}
/**
* Returns a list of all currencies available in the system
* @return Rest response of all currencies
*/
@ApiOperation(value = "Returns a list of all currencies ordered by priority", response = CurrencyListResponse.class)
@RequestMapping(value="", method=RequestMethod.GET, produces="application/json")
public ResponseEntity<RestResponse> getCurrencies() {
return new CurrencyListResponse(currencyService.getAllCurrencies()).response(HttpStatus.OK);
}
}
这是我当前的 swagger 配置;
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public SecurityConfiguration security() {
return SecurityConfigurationBuilder.builder()
.clientId("12345")
.clientSecret("12345")
.scopeSeparator(" ")
.useBasicAuthenticationWithAccessCodeGrant(true)
.build();
}
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.xompare.moo.controllers"))
.build()
.securitySchemes(Arrays.asList(securityScheme()))
.securityContexts(Arrays.asList(securityContext()))
.apiInfo(metaData());
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(Arrays.asList(new SecurityReference("spring_oauth", scopes())))
.forPaths(PathSelectors.regex("/.*"))
.build();
}
private AuthorizationScope[] scopes() {
AuthorizationScope[] scopes = {
new AuthorizationScope("read", "for read operations"),
new AuthorizationScope("write", "for write operations") };
return scopes;
}
public SecurityScheme securityScheme() {
GrantType grantType = new ClientCredentialsGrant("http://localhost:8080/oauth/token");
SecurityScheme oauth = new OAuthBuilder().name("spring_oauth")
.grantTypes(Arrays.asList(grantType))
.scopes(Arrays.asList(scopes()))
.build();
return oauth;
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
此时通过 spring 进行身份验证非常有效,我唯一的问题是让它与 Swagger UI 一起工作。
在阅读了这个 link 的内容后,我设法通过从 swagger-ui 版本 2.8.0 恢复到 2.7.0 来解决这个问题,这表明这是版本 2.8.0 的问题
我认为您需要在密钥前添加 "Bearer ",就像此处显示的那样 post:
我正在使用 Spring Boot to build a REST API。我添加了 Swagger-ui 来处理文档。我在实现客户端身份验证流程时遇到了问题,问题是我可以通过基本身份验证获得 swagger-ui 来授权提供的 client-id(username) 和 client-secret(password),但是 swagger UI 似乎没有应用到端点调用的结果访问令牌。
确认一下,我的授权流程; - 使用基本身份验证将 base64 编码的 username/password & grant_type=client_credentials 发送到 /oauth/token。 Spring returns 一个 access_token - 在以后的 API 调用中,使用提供的 access_token 作为承载令牌
我认为问题可能是因为我需要在我的控制器中的每个方法上放置一些东西来告诉 swagger 端点 requires 身份验证和什么类型,但我找不到任何明确的有关如何执行此操作的文档,我不知道是否需要对我的 swagger 配置应用任何进一步的更改。
这是一个控制器示例(删除了大多数方法以减小大小);
@Api(value="Currencies", description="Retrieve, create, update and delete currencies", tags = "Currencies")
@RestController
@RequestMapping("/currency")
public class CurrencyController {
private CurrencyService currencyService;
public CurrencyController(@Autowired CurrencyService currencyService) {
this.currencyService = currencyService;
}
/**
* Deletes the requested currency
* @param currencyId the Id of the currency to delete
* @return 200 OK if delete successful
*/
@ApiOperation(value = "Deletes a currency item", response = ResponseEntity.class)
@RequestMapping(value="/{currencyId}", method=RequestMethod.DELETE)
public ResponseEntity<?> deleteCurrency(@PathVariable("currencyId") Long currencyId) {
try {
currencyService.deleteCurrencyById(currencyId);
} catch (EntityNotFoundException e) {
return new ErrorResponse("Unable to delete, currency with Id " + currencyId + " not found!").response(HttpStatus.NOT_FOUND);
}
return new ResponseEntity(HttpStatus.OK);
}
/**
* Returns a single currency by it's Id
* @param currencyId the currency Id to return
* @return the found currency item or an error
*/
@ApiOperation(value = "Returns a currency item", response = CurrencyResponse.class)
@RequestMapping(value="/{currencyId}", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<RestResponse> getCurrency(@PathVariable("currencyId") Long currencyId) {
Currency currency = null;
try {
currency = currencyService.findById(currencyId);
} catch (EntityNotFoundException e) {
return new ErrorResponse("Currency with Id " + currencyId + " could not be found!").response(HttpStatus.NOT_FOUND);
}
return new CurrencyResponse(currency).response(HttpStatus.OK);
}
/**
* Returns a list of all currencies available in the system
* @return Rest response of all currencies
*/
@ApiOperation(value = "Returns a list of all currencies ordered by priority", response = CurrencyListResponse.class)
@RequestMapping(value="", method=RequestMethod.GET, produces="application/json")
public ResponseEntity<RestResponse> getCurrencies() {
return new CurrencyListResponse(currencyService.getAllCurrencies()).response(HttpStatus.OK);
}
}
这是我当前的 swagger 配置;
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public SecurityConfiguration security() {
return SecurityConfigurationBuilder.builder()
.clientId("12345")
.clientSecret("12345")
.scopeSeparator(" ")
.useBasicAuthenticationWithAccessCodeGrant(true)
.build();
}
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.xompare.moo.controllers"))
.build()
.securitySchemes(Arrays.asList(securityScheme()))
.securityContexts(Arrays.asList(securityContext()))
.apiInfo(metaData());
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(Arrays.asList(new SecurityReference("spring_oauth", scopes())))
.forPaths(PathSelectors.regex("/.*"))
.build();
}
private AuthorizationScope[] scopes() {
AuthorizationScope[] scopes = {
new AuthorizationScope("read", "for read operations"),
new AuthorizationScope("write", "for write operations") };
return scopes;
}
public SecurityScheme securityScheme() {
GrantType grantType = new ClientCredentialsGrant("http://localhost:8080/oauth/token");
SecurityScheme oauth = new OAuthBuilder().name("spring_oauth")
.grantTypes(Arrays.asList(grantType))
.scopes(Arrays.asList(scopes()))
.build();
return oauth;
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
此时通过 spring 进行身份验证非常有效,我唯一的问题是让它与 Swagger UI 一起工作。
在阅读了这个 link 的内容后,我设法通过从 swagger-ui 版本 2.8.0 恢复到 2.7.0 来解决这个问题,这表明这是版本 2.8.0 的问题
我认为您需要在密钥前添加 "Bearer ",就像此处显示的那样 post: