Пользовательский интерфейс Spring Boot и Swagger. Установить токен JWT

У меня такая конфигурация 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, когда я нажимаю кнопку «Авторизовать», я ввожу свой токен JWT в поле значения eyJhbGc..nN84qrBg. Теперь я ожидаю, что любой запрос, который я делаю через пользовательский интерфейс Swagger, будет содержать JWT в заголовке. Однако это не так. Ни один запрос не содержит заголовка авторизации.

Что мне не хватает?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
27
0
44 258
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ваш код правильный.

ошибка есть в Springfox-swagger-ui / Springfox-swagger2 версии 2.8.0 и, похоже, в 2.9.2. Я подозреваю, что вы используете версию, затронутую этой ошибкой.

Я просто перешел на 2.7.0, и он работал отлично.

Я хочу разбить свой монитор. Примерно 4 часа я ищу, почему мой код не работает, пока я не столкнулся с вашим ответом и не понял, что версия чванства тоже была моей проблемой. Спасибо чувак. ты спас мне день :)

Morteza Bandi 18.10.2020 15:08
Ответ принят как подходящий

Поддержка заголовка Authorization: Bearer [JWT_TOKEN] работает с версии 2.9.2.

В 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",
            "[email protected]");

        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

Нажмите «Авторизовать все запросы» и введите На предъявителя [JWT_TOKEN].

Press authorize then enter the Bearer JWT Token

Вуаля, ваши следующие запросы будут иметь заголовок JWT

Это сработало очень хорошо. Я не уверен, откуда импортирован AUTHORIZATION_HEADER, но я просто его жестко запрограммировал, и он работал так же хорошо.

Ickster 14.11.2018 04:09

Это статическая переменная, используемая в Spring Security и т. д. `Public static final String AUTHORIZATION_HEADER = " Authorization ";` (добавлено к самому ответу)

Matyas 14.11.2018 11:03

Хм. Интересно, было ли это устаревшим в версии Spring Security, которую я использую, или я просто пропустил это. Единственный импорт, который, как я помню, предлагал IntelliJ, был из другого пакета, и значение String было не тем, что я искал.

Ickster 14.11.2018 20:04

Я использовал точный код, как указано выше, с правильной зависимостью от maven, не показывает кнопку авторизации или не генерирует заголовок авторизации для api

webjockey 07.08.2020 00:24

Я сделал в точности так, как вы ответили. но токен не отправляется в заголовках запроса. ты можешь сказать мне, что я делаю не так?

Morteza Bandi 18.10.2020 15:01

это также работало с версией 3.0.0. Единственное, что я изменил, - это использовать Arrays.asList вместо Lists.newArrayList (поскольку я не использовал Guava) и переключиться с Swagger2 на OAS (@EnableOpenApi и DocumentationType.OAS_30).

Adrian B. 06.11.2020 16:25

Для swagger версии 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") })
      

молодец, сработало у меня, спасибо! Подчеркну, что в UI нужно указать полный заголовок Bearer <jwt>.

orid 13.05.2020 01:18

@orid Я рад, что смог помочь. Да, по стандарту впереди помещается «Bearer», однако эта конфигурация предназначена только для того, чтобы Swagger работал и отправлял в серверную часть заголовок с именем: «Авторизация». Однако значение этого заголовка зависит от разработчика.

moldovean 14.05.2020 17:02

@ApiOperation необходимо добавлять на уровне метода, а не класса. Пробовал это решение в версии 3.0.0. Спасибо)

Orkhan Hasanli 23.11.2020 02:07

Для быстрого решения я настроил свой документ с глобальным параметром заголовок авторизации в моем классе swaggerConfig.

    @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);
      }
    }

Об этом написал небольшой пост поле-авторизации-в-чванстве-пользовательском интерфейсе.

Пожалуйста, попробуйте что-то вроде ниже

 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());

Другие вопросы по теме