Java  

Implement JWT Authentication in Spring Boot?

Introduction

JWT (JSON Web Token) is a secure method for authenticating users in modern applications. Instead of storing session data on the server, JWT stores authentication information inside a token. This token is shared between the client and server, enabling a fast, secure, and scalable authentication process. In this article, we will learn how JWT authentication works and how to implement it step by step in a Spring Boot application, using simple, beginner-friendly language.

What is JWT?

JWT (JSON Web Token) is a compact, secure token used to verify a user's identity. It is commonly used in REST APIs.

A JWT has 3 parts:

  • Header – contains signing algorithm

  • Payload – contains user information

  • Signature – verifies token integrity

Example JWT structure:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Why Use JWT in Spring Boot?

JWT is popular because:

  • It is stateless (no session storage needed)

  • It works well for distributed systems

  • It is fast and secure

  • It supports mobile and web clients easily

Spring Boot + JWT is widely used in India for e-commerce apps, banking systems, and internal employee portals.

Step 1: Add Dependencies

Add Spring Security and JWT dependencies in pom.xml.

<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>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>

Step 2: Create a JWT Utility Class

This class will generate and validate tokens.

@Component
public class JwtUtil {

    private final String SECRET = "mysecretkey";

    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();
    }

    public String extractUsername(String token) {
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody().getSubject();
    }

    public boolean validateToken(String token, UserDetails userDetails) {
        String username = extractUsername(token);
        return username.equals(userDetails.getUsername());
    }
}

Step 3: Create a JWT Authentication Filter

This filter checks the token for each request.

@Component
public class JwtFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String authHeader = request.getHeader("Authorization");
        String token = null;
        String username = null;

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            token = authHeader.substring(7);
            username = jwtUtil.extractUsername(token);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);

            if (jwtUtil.validateToken(token, userDetails)) {
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }

        filterChain.doFilter(request, response);
    }
}

Step 4: Configure Spring Security

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtFilter jwtFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/authenticate").permitAll()
            .anyRequest().authenticated()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

Step 5: Create Authentication API

This API validates the user and returns the JWT token.

@RestController
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/authenticate")
    public String authenticate(@RequestBody AuthRequest authRequest) throws Exception {
        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword()));
        } catch (Exception e) {
            throw new Exception("Invalid username or password");
        }

        return jwtUtil.generateToken(authRequest.getUsername());
    }
}

Step 6: Testing the Flow

  1. Call /authenticate with username and password

  2. Receive the JWT token

  3. Send the token in header for every request:

Authorization: Bearer <token>
  1. Spring Boot validates token using the filter

Real-Life Example

A banking app in India uses JWT for secure login. Every time a user logs in, they get a token. All future API calls—balance check, fund transfer, statements—use this token. This prevents unauthorized access and protects sensitive financial data.

Best Practices

  • Store secret keys securely

  • Use long and complex JWT secrets

  • Set token expiration time

  • Refresh tokens periodically

  • Use HTTPS in production

Summary

JWT authentication in Spring Boot provides a secure and scalable way to protect REST APIs. By generating tokens, validating them, and integrating with Spring Security, developers can create robust authentication systems for web and mobile applications. JWT is widely used in modern backend systems due to its speed, stateless architecture, and flexibility.