Configure JWT with Spring Boot and Swagger UI

In the previous tutorial, we have seen Spring Boot REST API Documentation with Swagger.

In this tutorial, we will learn how to configure Swagger UI to include a JSON Web Token (JWT) when it calls our API.

Building Real-Time REST APIs with Spring Boot course at https://courses.javaguides.net/p/building-rest-api-with-spring-boot

We will add Swagger configuration code in the Spring boot application to enable the Authorization option on Swagger UI to include JWT.

Swagger UI provides custom configurations to set up JWT, which can be helpful when dealing with our application authorization. After authorizing in Swagger UI, all the requests will automatically include our JWT.

Adding Maven Dependency to Spring Boot Project

In this example, we'll be using springfox-boot-starter, which includes all the necessary dependencies to start working with Swagger and Swagger UI. 

Let's pom.xml file and add the below maven dependencies to it:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

Swagger Configuration

Let's create a SwaggerConfig class and annotate with @Configuration annotation. The configuration of Swagger mainly centers around the Docket bean so let's add the below code to SwaggerConfig class:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Configuration
public class SwaggerConfig {

    public static final String AUTHORIZATION_HEADER = "Authorization";

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

    private ApiInfo apiInfo(){
        return new ApiInfo(
                "Spring Boot Blog REST APIs",
                "Spring Boot Blog REST API Documentation",
                "1",
                "Terms of service",
                new Contact("Ramesh Fadatare", "www.javaguides.net", "ramesh@gmail.com"),
                "License of API",
                "API license URL",
                Collections.emptyList()
        );
    }

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .securityContexts(Arrays.asList(securityContext()))
                .securitySchemes(Arrays.asList(apiKey()))
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    private SecurityContext securityContext(){
        return SecurityContext.builder().securityReferences(defaultAuth()).build();
    }

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

Let's understand the above code.

We have added ApiKey to include JWT as an authorization header:

public static final String AUTHORIZATION_HEADER = "Authorization";

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

Next, let's configure the JWT SecurityContext with a global AuthorizationScope:

    private SecurityContext securityContext(){
        return SecurityContext.builder().securityReferences(defaultAuth()).build();
    }

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

And then, we configured our API Docket bean to include API info, security contexts, and security schemes:

private ApiInfo apiInfo(){
        return new ApiInfo(
                "Spring Boot Blog REST APIs",
                "Spring Boot Blog REST API Documentation",
                "1",
                "Terms of service",
                new Contact("Ramesh Fadatare", "www.javaguides.net", "ramesh@gmail.com"),
                "License of API",
                "API license URL",
                Collections.emptyList()
        );
    }

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .securityContexts(Arrays.asList(securityContext()))
                .securitySchemes(Arrays.asList(apiKey()))
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

Accessing Swagger UI

Let's say we are creating a blog application and when we start our application, we can access the Swagger UI at:
 

Here's a look at the Swagger UI with Authorize button:



Complete Course and Source Code

Building Real-Time REST APIs with Spring Boot at https://courses.javaguides.net/p/building-rest-api-with-spring-boot


Comments