Securing APIs is a vital part of backend development. In modern web applications, JWT (JSON Web Token) has become the de-facto standard for implementing stateless, token-based authentication. In this post, we’ll walk through implementing JWT in a Spring Boot application — covering key concepts, code snippets, and best practices.

🔍What is JWT?
JWT (JSON Web Token) is an open standard (RFC 7519) that defines a compact, URL-safe way of transmitting claims between two parties. It’s widely used for:

  • Stateless authentication
  • API authorization
  • Secure data exchange

⚙️ Step-by-Step Implementation: We’ll implement a simple Spring Boot application with JWT authentication. Steps include:

  • Setup Spring Boot Project
  • Create User Model and Repository
  • Generate JWT
  • Validate JWT
  •   Secure Endpoints
1️⃣ Setup Spring Boot Project

You can generate a Spring Boot project from https://start.spring.io with the following dependencies:

  • Spring Web
  • Spring Security
  • Spring Data JPA
  • H2 / MySQL
  • Lombok
  • JWT (via jjwt library or java-jwt)

2️⃣ Create User Model and Repository

 

3️⃣ JWT Utility Class – Generate & Validate Tokens

4️⃣ Authentication Filter – Validate Token on Requests

public class JwtRequestFilter extends OncePerRequestFilter {

@Autowired
private JwtUtil jwtUtil;

@Autowired
private UserDetailsService userDetailsService;

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

final String authHeader = request.getHeader(“Authorization”);

String username = null;
String jwt = null;

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

if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());

authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}

chain.doFilter(request, response);
}
}

5️⃣ Configure Spring Security

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Autowired
private JwtRequestFilter jwtRequestFilter;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeHttpRequests(auth -> auth
.requestMatchers(“/authenticate”).permitAll()
.anyRequest().authenticated()
)
.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}

6️⃣ Create Authentication Controller

@RestController
public class AuthController {

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private JwtUtil jwtUtil;

@Autowired
private UserDetailsService userDetailsService;

@PostMapping(“/authenticate”)
public ResponseEntity<?> createToken(@RequestBody AuthRequest authRequest) {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
);
} catch (AuthenticationException e) {
throw new RuntimeException(“Invalid credentials”);
}

final UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
final String jwt = jwtUtil.generateToken(userDetails.getUsername());

return ResponseEntity.ok(new AuthResponse(jwt));
}
}

📦 Request & Response Sample
Request:
POST /authenticate
Content-Type: application/json

{
“username”: “john”,
“password”: “password123”
}
Response:
{
“jwt”: “eyJhbGciOiJIUzI1NiIsInR5cCI6…”
}
Use this token in the Authorization header:

🛡️ Best Practices
Always sign JWTs with a strong secret or RSA key.

Keep tokens short-lived (e.g., 15 min – 1 hr).

Use refresh tokens for re-authentication.

Secure sensitive endpoints with roles (@PreAuthorize or hasRole()).

Avoid storing JWT in local storage (prefer HttpOnly cookies for web apps).

✅ Final Thoughts
JWT offers a simple, scalable, and stateless way to secure your Spring Boot APIs. With tools like jjwt or java-jwt, you can quickly integrate authentication mechanisms without relying on server sessions.