Search Tutorials


Spring Boot 3 + JWT + Swagger Example

Spring Boot 3 + JWT + Swagger Example

In a previous tutorial we looked at the basics of OpenAPI and implemented Swagger for Spring Boot 3 + MySQL + JPA + CRUD application. Also in another previous tutorial we implemented Spring Spring Boot3 + JWT Hello World Example. In this tutorial we will be implementing swagger configuration for this JWT example such that the requests can be authorized using swagger ui.

Video

This tutorial is explained in the below Youtube Video.

Implementation

We will be modifying the previous tutorial we implemented Spring Spring Boot3 + JWT Hello World Example.
We will be adding the swagger dependency to the pom.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.2.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.javainuse</groupId>
	<artifactId>boot-mysql-crud</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>boot-mysql-crud</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt-api</artifactId>
			<version>0.11.5</version>
		</dependency>
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt-impl</artifactId>
			<version>0.11.5</version>
		</dependency>
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt-jackson</artifactId>
			<version>0.11.5</version>
		</dependency>
		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
			<version>2.0.3</version>
		</dependency>

		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>




If we now go to swagger url - http://localhost:8080/swagger-ui/index.html we get the security exception 403.
Spring Boot 3 security JWT authentication swagger ui
Previously for JWT we had whitelisted the url /authenticated using which we generated the JWT. Next let us whitelist swagger urls also.
package com.javainuse.bootmysqlcrud.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class WebSecurityConfig { 

	private static final String[] WHITE_LIST_URL = { "/api/v1/auth/**", "/v2/api-docs", "/v3/api-docs",
			"/v3/api-docs/**", "/swagger-resources", "/swagger-resources/**", "/configuration/ui",
			"/configuration/security", "/swagger-ui/**", "/webjars/**", "/swagger-ui.html", "/api/auth/**",
			"/api/test/**", "/authenticate" };

	@Autowired
	private JwtRequestFilter jwtRequestFilter;

	@Bean
	public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
		return authConfig.getAuthenticationManager();
	}

	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.csrf(csrf -> csrf.disable())
				.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
				.authorizeHttpRequests(
						auth -> auth.requestMatchers(WHITE_LIST_URL).permitAll().anyRequest().authenticated());
		http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
		return http.build();
	}
}
If we now go to swagger url - http://localhost:8080/swagger-ui/index.html we are able to access the swagger ui.
Spring Boot 3 security JWT authentication swagger ui
However if we try to get list of employees using the url /employees using the swaggerui we get 403 exception.
Spring Boot 3 security JWT authentication swagger ui
Next we create a class named SwaggerConfig that uses the Spring Framework's @Configuration annotation to define a bean for generating Swagger documentation. We create an OpenAPI object with information about the authentication service, including the title, description. Most importantly in this config we create a security scheme for bearer authentication, specifying the scheme name, type, and bearer format.
package com.javainuse.bootmysqlcrud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;

@Configuration
public class SwaggerConfig {

	@Bean
	public OpenAPI customOpenAPI() {
		
		return new OpenAPI()
				.info(new Info().title("JavaInUse Authentication Service"))				
				.addSecurityItem(new SecurityRequirement().addList("JavaInUseSecurityScheme"))
				.components(new Components().addSecuritySchemes("JavaInUseSecurityScheme", new SecurityScheme()
						.name("JavaInUseSecurityScheme").type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
		
	}
}
If we now go to swagger url - http://localhost:8080/swagger-ui/index.html we get the Swagger UI.
Spring Boot 3 security JWT authentication swagger ui
  1. Create the JWT -
    Hit the url - /authenticate to which we pass the username and password.
    Spring Boot 3 security JWT authentication swagger using username and password
  2. Provide the JWT to swagger for authorization-
    Using the authorize button provide the JWT
    Spring Boot 3 security JWT authentication swagger authorize button
  3. Access employees url -
    If we now hit the url /employees we get back the list of employees.
    Spring Boot 3 security JWT authentication swagger get employees

Download Source Code

Download it -
Spring Boot 3 + JWT Example