У меня такая конфигурация 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 в заголовке. Однако это не так.
Ни один запрос не содержит заголовка авторизации.
Что мне не хватает?




Ваш код правильный.
ошибка есть в Springfox-swagger-ui / Springfox-swagger2 версии 2.8.0 и, похоже, в 2.9.2. Я подозреваю, что вы используете версию, затронутую этой ошибкой.
Я просто перешел на 2.7.0, и он работал отлично.
Authorization: Bearer [JWT_TOKEN] работает с версии 2.9.2.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"
@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Это сработало очень хорошо. Я не уверен, откуда импортирован AUTHORIZATION_HEADER, но я просто его жестко запрограммировал, и он работал так же хорошо.
Это статическая переменная, используемая в Spring Security и т. д. `Public static final String AUTHORIZATION_HEADER = " Authorization ";` (добавлено к самому ответу)
Хм. Интересно, было ли это устаревшим в версии Spring Security, которую я использую, или я просто пропустил это. Единственный импорт, который, как я помню, предлагал IntelliJ, был из другого пакета, и значение String было не тем, что я искал.
Я использовал точный код, как указано выше, с правильной зависимостью от maven, не показывает кнопку авторизации или не генерирует заголовок авторизации для api
Я сделал в точности так, как вы ответили. но токен не отправляется в заголовках запроса. ты можешь сказать мне, что я делаю не так?
это также работало с версией 3.0.0. Единственное, что я изменил, - это использовать Arrays.asList вместо Lists.newArrayList (поскольку я не использовал Guava) и переключиться с Swagger2 на OAS (@EnableOpenApi и DocumentationType.OAS_30).
Для swagger версии 2.9.2
Создайте класс 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");
}
Затем аннотируйте каждый API, на который вы хотите отправить этот заголовок авторизации:
@ApiOperation(value = "", authorizations = { @Authorization(value = "jwtToken") })
молодец, сработало у меня, спасибо! Подчеркну, что в UI нужно указать полный заголовок Bearer <jwt>.
@orid Я рад, что смог помочь. Да, по стандарту впереди помещается «Bearer», однако эта конфигурация предназначена только для того, чтобы Swagger работал и отправлял в серверную часть заголовок с именем: «Авторизация». Однако значение этого заголовка зависит от разработчика.
@ApiOperation необходимо добавлять на уровне метода, а не класса. Пробовал это решение в версии 3.0.0. Спасибо)
Для быстрого решения я настроил свой документ с глобальным параметром заголовок авторизации в моем классе 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());
Я хочу разбить свой монитор. Примерно 4 часа я ищу, почему мой код не работает, пока я не столкнулся с вашим ответом и не понял, что версия чванства тоже была моей проблемой. Спасибо чувак. ты спас мне день :)