JWT Authentication in Spring Boot

JWT Authentication in Spring Boot

When building secure APIs with Spring Boot, you often need to authenticate users. One popular and modern method is using JWT (JSON Web Tokens).

In this guide, we’ll explain how JWT authentication works in Spring Boot—and how to implement it step by step.


What is JWT?

JWT (JSON Web Token) is a compact, secure way to represent information between two parties.

It’s used to verify users without needing to store session data on the server.

A JWT contains three parts:

HEADER.PAYLOAD.SIGNATURE

Example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiJ1c2VyMSIsImlhdCI6MTY3Njg0. qwerty-signature-example

๐Ÿ” Why Use JWT in Spring Boot?

  • Stateless: No need to store sessions

  • Scalable: Works well in distributed systems (e.g., microservices)

  • Fast: No database call needed for every request

  • Secure: Signed with a secret key


⚙️ How JWT Authentication Works

  1. User Logs In with username and password

  2. Server authenticates and generates a JWT

  3. Client stores JWT (usually in localStorage or cookies)

  4. Client sends JWT in the Authorization header with each request

  5. Server verifies the JWT and grants access


๐Ÿ› ️ Step-by-Step: Implementing JWT in Spring Boot

๐Ÿ”ธ 1. Add Required Dependencies

In your pom.xml (Maven):

<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>

Spring Boot also needs:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>

๐Ÿ”ธ 2. Create a JWT Utility Class

@Component public class JwtUtil { private final String SECRET_KEY = "mysecret"; public String generateToken(String username) { return Jwts.builder() .setSubject(username) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1 hour .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } public String extractUsername(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody() .getSubject(); } public boolean validateToken(String token, UserDetails userDetails) { String username = extractUsername(token); return (username.equals(userDetails.getUsername())); } }

๐Ÿ”ธ 3. 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) throws Exception { try { authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( authRequest.getUsername(), authRequest.getPassword()) ); } catch (BadCredentialsException e) { throw new Exception("Invalid credentials", e); } final UserDetails userDetails = userDetailsService .loadUserByUsername(authRequest.getUsername()); final String jwt = jwtUtil.generateToken(userDetails.getUsername()); return ResponseEntity.ok(new AuthResponse(jwt)); } }

๐Ÿ”ธ 4. Create Request and Response Models

@Data public class AuthRequest { private String username; private String password; } @Data @AllArgsConstructor public class AuthResponse { private String jwt; }

๐Ÿ”ธ 5. JWT Filter (To Check Token in Every 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 { 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()); SecurityContextHolder.getContext().setAuthentication(authToken); } } filterChain.doFilter(request, response); } }

๐Ÿ”ธ 6. Spring Security Configuration

@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private JwtFilter jwtFilter; @Autowired private UserDetailsService userDetailsService; @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests().antMatchers("/authenticate").permitAll() .anyRequest().authenticated(); http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } }

๐Ÿงช How to Use

  1. Call POST /authenticate with username and password

  2. Get the JWT token in the response

  3. Use this token in the Authorization header of all future API calls:

Authorization: Bearer your.jwt.token

๐Ÿ“Œ Benefits of JWT in Spring Boot

FeatureBenefit
Stateless AuthNo need to manage sessions
LightweightJWT is a small, compact token
ScalableWorks well in microservices
SecureCan be signed and encrypted

Final Thoughts

JWT is a powerful way to secure your Spring Boot APIs.
With just one token, you can authorize users across multiple endpoints—without sessions or cookies.

It’s fast, clean, and ideal for modern REST APIs and mobile apps. 


Read More 

Comments

Popular posts from this blog

What is WebDriver in Selenium? Explained with Java

Tosca System Requirements and Installation Guide (Step-by-Step)

Why Choose Python for Full-Stack Web Development