Spring Boot & Swagger UI. Set JWT token
54,799
Solution 1
Support for Authorization: Bearer [JWT_TOKEN]
header is working as of version 2.9.2
Added the following dependencies to 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"
Configured Swagger via
@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));
}
}
Access the ui via http://host:port/<context-root>/swagger-ui.html
Press Authorize all requests and enter Bearer [JWT_TOKEN]
Voila your next requests will have the JWT header
Solution 2
For swagger version 2.9.2
-
Create a SwaggerConfig class.
@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"); }
-
Then annotate each API you would like to send this Authorization header to with:
@ApiOperation(value = "", authorizations = { @Authorization(value="jwtToken") })
-
Solution 3
Your code is correct.
There is a bug in springfox-swagger-ui/springfox-swagger2 version 2.8.0 and it seems 2.9.2 as well. I suspect you are using a version effected by this bug.
I simply downgraded to 2.7.0 and it worked perfectly.
Author by
isADon
Updated on March 30, 2021Comments
-
isADon about 3 years
I have a Swagger config like this
@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(); } }
In the Swagger UI when I click on the Authorize button I enter my JWT token in the value field
eyJhbGc..nN84qrBg
. Now I expect that any request I do through the Swagger UI will contain the JWT in the header. However, that is not the case. No request contains a Authorization header.What am I missing?
-
Ickster over 5 yearsThis worked very well. I'm not sure where the
AUTHORIZATION_HEADER
is imported from, but I just hard-coded it and it worked just as well. -
Matyas over 5 yearsIt is a static variable used across Spring Security / etc. ` public static final String AUTHORIZATION_HEADER = "Authorization";` (added to the answer itself)
-
Ickster over 5 yearsHmmm. I wonder if that was deprecated in the version of Spring Security I'm using, or if I just missed it. The only import I recall IntelliJ suggesting was from a different package and the String value wasn't what I was looking for.
-
orid about 4 yearswell done, worked for me, thanks! Just to emphasize that in the UI you need to specify the full header "Bearer <jwt>"
-
moldovean about 4 years@orid I am glad I could help. Yes, the standard is to put 'Bearer' in front, however this config is just for Swagger to work and send to back-end a header with name: "Authorization". The value of this header however is up to the developer.
-
webjockey almost 4 yearsI used exact code as above with correct maven dependency, does not show authorize button or does not generate authorization header for the api's
-
Morteza over 3 yearsI did exactly as your answer. but, the token is not sent in request headers. can you tell me what am i doing wrong?
-
Morteza over 3 yearsI wanna smash my monitor. It is about 4 hours that I am searching for why my code is not working, till I faced your answer and figured out that swagger version was my problem too. thanks man. you saved my day :)
-
Adrian B. over 3 yearsthis worked with version 3.0.0 as well. The only thing that I changes was to use
Arrays.asList
instead ofLists.newArrayList
(as I didn't use Guava) and to switch from Swagger2 to OAS (@EnableOpenApi
andDocumentationType.OAS_30
) -
Orkhan Hasanli over 3 years@ApiOperation must be added on method level, not to the class. Tried this solution in 3.0.0 version. Thank you)
-
Shashi Ranjan almost 2 yearsThis code has compilation issue.