DEV Community

Rajesh Mishra
Rajesh Mishra

Posted on Originally published at howtostartprogramming.in

Spring Boot REST API with JWT authentication step by step — Complete Guide

Spring Boot REST API with JWT authentication step by step — Complete Guide

A practical, in-depth guide to Spring Boot REST API with JWT authentication step by step with examples.

INTRO

Every production‑grade microservice needs a way to prove who is calling it and what they’re allowed to do. The naive approach—hard‑coding usernames, storing sessions in memory, or sprinkling @PreAuthorize checks everywhere—breaks down as soon as you scale beyond a single instance or need mobile clients. The result is a leaky security perimeter, duplicated code, and a maintenance nightmare.

JSON Web Tokens (JWT) give you a stateless, portable credential that can travel across domains, be cached by CDNs, and be verified without hitting a database on each request. Yet the first time you try to wire JWT into a Spring Boot REST API you’ll hit a wall of configuration classes, filter chains, and token‑parsing boilerplate. The pain isn’t the concept of JWT; it’s the lack of a clear, step‑by‑step roadmap that shows you exactly where each piece belongs.

That’s why a concise, hands‑on guide matters. It should walk you from an empty Spring Boot project to a fully secured API, explain why each configuration decision exists, and surface the common pitfalls that turn a simple token check into a security hole. The guide linked below does exactly that, letting you focus on business logic instead of wrestling with Spring Security internals.

WHAT YOU'LL LEARN

  • How to generate and sign JWTs using a symmetric secret and expose a clean /auth/login endpoint.
  • The anatomy of a Spring Security filter that extracts the token from the Authorization header and populates the security context.
  • Configuring WebSecurityConfigurerAdapter (or the newer component‑based approach) to protect selected routes while leaving public endpoints open.
  • Implementing role‑based access with @PreAuthorize and custom GrantedAuthority extraction from JWT claims.
  • Testing the authentication flow with MockMvc and Postman, including token expiration handling.
  • Production‑ready tips: secret management, token revocation strategies, and CORS considerations for SPA clients.

A SHORT CODE SNIPPET

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final JwtUtil jwtUtil;
private final UserDetailsService userDetailsService;

public JwtAuthenticationFilter(JwtUtil jwtUtil, UserDetailsService userDetailsService) {
this.jwtUtil = jwtUtil;
this.userDetailsService = userDetailsService;
}

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
String username = null;
String token = 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());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}
Enter fullscreen mode Exit fullscreen mode

The snippet shows the core of JWT validation: pulling the token from the header, extracting the username, loading user details, and finally populating the SecurityContext. The surrounding guide explains each helper method and how to wire the filter into the security chain.

KEY TAKEAWAYS

  • Stateless security: JWT removes the need for server‑side session storage, but you must still enforce token expiration and rotate signing keys regularly.
  • Filter placement matters: Register the JWT filter before UsernamePasswordAuthenticationFilter to ensure the security context is populated for downstream authorisation checks.
  • Claims are your ACL: Embedding roles or permissions in the token lets you offload most authorisation decisions to Spring’s expression language (@PreAuthorize("hasRole('ADMIN')")).
  • Don’t ignore revocation: In a pure JWT world you can’t instantly invalidate a token; the guide covers blacklist approaches and short‑lived access tokens paired with refresh tokens.

👉 Read the complete guide with step-by-step examples, common mistakes, and production tips:

Spring Boot REST API with JWT authentication step by step — Complete Guide

Top comments (0)