Spring Boot& Swagger UI。设置JWT令牌

时间:2018-05-26 17:18:58

标签: spring-boot swagger swagger-ui swagger-2.0

我有一个像这样的Swagger配置

@EnableSwagger2
@Configuration
public class SwaggerConfig {
    @Bean
    public Docket api() {
        List<SecurityScheme> schemeList = new ArrayList<>();
        schemeList.add(new ApiKey(HttpHeaders.AUTHORIZATION, "JWT", "header"));
        return new Docket(DocumentationType.SWAGGER_2)
                .produces(Collections.singleton("application/json"))
                .consumes(Collections.singleton("application/json"))
                .ignoredParameterTypes(Authentication.class)
                .securitySchemes(schemeList)
                .useDefaultResponseMessages(false)
                .select()
                .apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot")))
                .paths(PathSelectors.any())
                .build();
    }
}

在Swagger UI中,当我点击“授权”按钮时,我在值字段eyJhbGc..nN84qrBg中输入了我的JWT标记。现在我希望通过Swagger UI做的任何请求都会在标题中包含JWT。但事实并非如此。 没有请求包含授权标头。

我错过了什么?

5 个答案:

答案 0 :(得分:14)

自{2.9.2版本开始,支持Authorization: Bearer [JWT_TOKEN]标头

向build.gradle添加了以下依赖项

compile("io.springfox:springfox-swagger2:2.9.2") {
    exclude module: 'mapstruct' // necessary in my case to not end up with multiple mapstruct versions
}
compile "io.springfox:springfox-bean-validators:2.9.2"
compile "io.springfox:springfox-swagger-ui:2.9.2"

通过以下方式配置Swagger

@Configuration
@EnableSwagger2
@Import(springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration.class)
public class SwaggerConfiguration {

    public static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String DEFAULT_INCLUDE_PATTERN = "/api/.*";
    private final Logger log = LoggerFactory.getLogger(SwaggerConfiguration.class);

    @Bean
    public Docket swaggerSpringfoxDocket() {
        log.debug("Starting Swagger");
        Contact contact = new Contact(
            "Matyas Albert-Nagy",
            "https://justrocket.de",
            "matyas@justrocket.de");

        List<VendorExtension> vext = new ArrayList<>();
        ApiInfo apiInfo = new ApiInfo(
            "Backend API",
            "This is the best stuff since sliced bread - API",
            "6.6.6",
            "https://justrocket.de",
            contact,
            "MIT",
            "https://justrocket.de",
            vext);

        Docket docket = new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo)
            .pathMapping("/")
            .apiInfo(ApiInfo.DEFAULT)
            .forCodeGeneration(true)
            .genericModelSubstitutes(ResponseEntity.class)
            .ignoredParameterTypes(Pageable.class)
            .ignoredParameterTypes(java.sql.Date.class)
            .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class)
            .directModelSubstitute(java.time.ZonedDateTime.class, Date.class)
            .directModelSubstitute(java.time.LocalDateTime.class, Date.class)
            .securityContexts(Lists.newArrayList(securityContext()))
            .securitySchemes(Lists.newArrayList(apiKey()))
            .useDefaultResponseMessages(false);

        docket = docket.select()
            .paths(regex(DEFAULT_INCLUDE_PATTERN))
            .build();
        watch.stop();
        log.debug("Started Swagger in {} ms", watch.getTotalTimeMillis());
        return docket;
    }


    private ApiKey apiKey() {
        return new ApiKey("JWT", AUTHORIZATION_HEADER, "header");
    }

    private SecurityContext securityContext() {
        return SecurityContext.builder()
            .securityReferences(defaultAuth())
            .forPaths(PathSelectors.regex(DEFAULT_INCLUDE_PATTERN))
            .build();
    }

    List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope
            = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Lists.newArrayList(
            new SecurityReference("JWT", authorizationScopes));
    }
}

通过http://host:port/<context-root>/swagger-ui.html

访问ui

按授权所有请求,然后输入承载者[JWT_TOKEN]

Press authorize then enter the Bearer JWT Token

Voila您的下一个请求将具有JWT标头

enter image description here

答案 1 :(得分:6)

对于摇摇欲坠的版本2.9.2

  1. 创建SwaggerConfig类。

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo())
                .securitySchemes(Arrays.asList(apiKey()));
    }
    
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Sig-Predict REST API Document")
                .description("work in progress")
                .termsOfServiceUrl("localhost")
                .version("1.0")
                .build();
    }
    
    private ApiKey apiKey() {
        return new ApiKey("jwtToken", "Authorization", "header");
    }
    
    1. 然后用以下注释您要将此授权标头发送到的每个API:

      @ApiOperation(value = "", authorizations = { @Authorization(value="jwtToken") })
      

答案 2 :(得分:1)

您的代码正确。

bug / springfox-swagger-ui的2.8.0版本中有一个springfox-swagger2,似乎也是2.9.2。我怀疑您使用的是受此错误影响的版本。

我只是将其降级为2.7.0,并且运行良好。

答案 3 :(得分:0)

为快速解决方案,我在swaggerConfig类中为全局文件配置了 authorization标头

    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
      private static final Set<String> DEFAULT_PRODUCES_CONSUMES = new HashSet<String>(Arrays.asList("application/json"));
    
      @Bean
      public Docket api() {
        ParameterBuilder parameterBuilder = new ParameterBuilder();
        parameterBuilder.name("Authorization")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .description("JWT token")
                .required(true)
                .build();
        List<Parameter> parameters = new ArrayList<>();
        parameters.add(parameterBuilder.build());
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(DEFAULT_API_INFO)
            .produces(DEFAULT_PRODUCES_CONSUMES)
            .consumes(DEFAULT_PRODUCES_CONSUMES)
            .select()
            .build()
            // Setting globalOperationParameters ensures that authentication header is applied to all APIs
            .globalOperationParameters(parameters);
      }
    }

为此写了一篇小文章authorization-field-in-swagger-ui

答案 4 :(得分:0)

请尝试以下操作

 return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.any()).paths(PathSelectors.regex("/api/v1/.*"))
            .build().groupName("API")
            .globalOperationParameters(newArrayList(
                    new ParameterBuilder().name(HttpHeaders.AUTHORIZATION).description("Authorization token").required(true)
                            .modelRef(new ModelRef("string")).parameterType("header").required(true).build()))
            .apiInfo(apiInfo());