【问题标题】:Spring boot + Swagger UI how to tell endpoint to require bearer tokenSpring boot + Swagger UI 如何告诉端点需要不记名令牌
【发布时间】:2018-06-21 06:30:22
【问题描述】:

我正在使用 Spring Boot 构建 REST API。我添加了 Swagger-ui 来处理文档。我在实现客户端身份验证流入 swagger 时遇到问题,问题是我可以通过基本身份验证让 swagger-ui 授权提供的客户端 ID(用户名)和客户端密码(密码),但 swagger UI 没有然后似乎正在将生成的访问令牌应用于端点调用。

确认,我的授权过程; - 使用基本身份验证将 base64 编码的用户名/密码和 grant_type=client_credentials 发送到 /oauth/token。 Spring 返回一个 access_token - 在未来的 API 调用中,使用提供的 access_token 作为不记名令牌

我认为问题可能是因为我需要在我的控制器中的每个方法上放置一些东西来告诉 swagger 端点需要身份验证以及什么类型,但是我找不到任何关于如何执行此操作的明确文档,并且我不知道是否需要对我的 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);
    }

}

这是我当前的招摇配置;

@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 一起使用。

【问题讨论】:

    标签: spring-boot swagger-ui


    【解决方案1】:

    我认为您需要在密钥前添加“Bearer”,就像在这篇文章中显示的那样: Spring Boot & Swagger UI. Set JWT token

    【解决方案2】:

    在阅读此链接的内容后,我设法通过从 swagger-ui 版本 2.8.0 恢复到 2.7.0 来解决此问题,这表明版本 2.8.0 存在问题

    https://github.com/springfox/springfox/issues/1961

    【讨论】:

      猜你喜欢
      • 2019-12-30
      • 1970-01-01
      • 2020-12-26
      • 2019-09-27
      • 1970-01-01
      • 2020-11-11
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多