Spring Boot Jwt Authentication
By AmarSivas | | Updated : 2022-04-23 | Viewed : 21 times

In this tutorial, we are going to learn Spring JWT Authentication with a simple example. The Spring application that we implement will use the JWT tokens. Using decoding of JWT Token, Spring application provides authentication and authorization.
Table of Contents:
Spring Security Terminology
Now, we will focus on the basic terminology of the
Roles and Privileges
Now we will discuss the Spring Security authentication components and what they defined for.
Spring Security Authentication Components
We will discuss the entire Spring Security architecture in a separate tutorial with a simple explanation.
Spring Boot JWT Authentication Example
Now we will try to start the implement the JWT Authentication in Spring Boot.
Maven Dependencies
You need to download the project using spring initialized using this link, then add the below given dependencies to set up the spring JWT token based authentication project.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
In this project, we are using the Java 12. We need to set up JAXB dependencies separately. Please find the same dependencies for the same.
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
<scope>runtime</scope>
</dependency>
This below dependency performs the decoding and encoding JWT tokens in java. In the current application, it performs the authentication and authorization using encoding of JWT token to validation of user and performing user authorization.
Now, we will look into implementing the Spring project for JWT token based authentication.
Implement Spring Security JWT Project
Write Code For WebSecurityConfig
Please see the below code snippet for WebSecurityConfig Class.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtUnauthorizedHandler jwtUnauthorizedHandler;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/jwt/validate/userToken","/jwt/validate/adminToken").permitAll()
.anyRequest().authenticated().and()
.exceptionHandling().authenticationEntryPoint(jwtUnauthorizedHandler).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Write Code For JwtAuthenticationFilter
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private UserService userService;
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String requestTokenHeader = request.getHeader("Authentication-Data");
Optional<String> optionalJwtToken = jwtTokenUtils.getJwtFromRequest(request);
if (optionalJwtToken.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) {
String jwtToken = optionalJwtToken.get();
Optional<Jws<Claims>> OptionalClaims = jwtTokenUtils.getClaimsFromJwtToken(jwtToken);
if (OptionalClaims.isPresent()) {
Jws<Claims> jwsClaims = OptionalClaims.get();
Claims claimsBody = jwsClaims.getBody();
String userName = (String) claimsBody.get("userName");
String displayName = (String) claimsBody.get("displayName");
String roleName = (String) claimsBody.get("roleName");
String isEnabled = (String) claimsBody.get("isEnabled");
String email = (String) claimsBody.get("email");
String password = (String) claimsBody.get("password");
UserDetails userDetails = this.userService.loadUser(userName,displayName,roleName,isEnabled,email,password);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
Write Code For JwtUnauthorizedHandler
@Component
public class JwtUnauthorizedHandler implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized User");
}
}
Write Code For JwtAuthController
@RestController
@RequestMapping(value = "/jwt")
public class JwtAuthController {
@Autowired
private JWTAuthService jWTAuthService;
@PreAuthorize("hasRole('USER')")
@PostMapping(value = "/validate/userToken", produces = "application/json")
public ResponseEntity<?> validateUserToken(@RequestBody ValidateTokenRequest validateTokenRequest) {
return jWTAuthService.validateUserToken();
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping(value = "/validate/adminToken", produces = "application/json")
public ResponseEntity<?> validateAdminToken(@RequestBody ValidateTokenRequest validateTokenRequest) {
return jWTAuthService.validateAdminToken();
}
}
And there are other class files are need to be implemented. You can find the entire application code in the GitHub repo here Spring-boot-Jwt-without-Database. We now execute the about the requests to check the application is working fine or not.
Generate JWT Tokens For User And Admin
Please open the URL https://jwt.io/ and provide payload as given below.
{
"name": "1234567890",
"userName": "docsconsoleUser",
"roleType": "user",
"isEnabled": "yes",
"password":"testPassword",
"email":"testuser@docsconsole.com"
}
Now you can see the token generated as below. So we are going to pass the same token for the user. In payload, you can change details as per your needs.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMTIzNDU2Nzg5MCIsInVzZXJOYW1lIjoiZG9jc2NvbnNvbGVVc2VyIiwicm9sZU5hbWUiOiJ1c2VyIiwiaXNFbmFibGVkIjoieWVzIiwicGFzc3dvcmQiOiJ0ZXN0UGFzc3dvcmQiLCJlbWFpbCI6InRlc3R1c2VyQGRvY3Njb25zb2xlLmNvbSJ9.8PIALnlkazjcZ5qpnLqfyU9_B3vkMElLp_g4JERNPbU
In the same way, we can create the JWT token for the admin role. If you want used regenerated JWT token, you can refer the project folder in GitHub.
Test Spring Boot JWT Token Based Authentication
We will test the project using the postman. You can find the Postman collection in the project itself. Please find the below given screenshots for the same.


Please find GitHub repo here Spring-boot-Jwt-without-Database