JWT Authentication
Imagine you have a VIP pass to a concert. The pass contains your name and access level. You show it at the entrance, and security lets you in without checking your ID again. JWT (JSON Web Token) works the same way – it's a token that proves who you are and what you can access.
What is JWT?
JWT is a compact, URL-safe token that contains JSON data. It consists of three parts:
- Header – Token type and algorithm.
- Payload
- Signature – Verifies token hasn't been tampered with.
JWT Authentication Flow:
1. User logs in with username/password.
2. Server validates credentials and creates JWT.
3. Server returns JWT to client.
4. Client sends JWT in Authorization header for subsequent requests.
5. Server validates JWT and grants access.
Add Dependencies:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
JWT Utility Class:
@Component
public class JwtUtil {
private String secret = "mySecretKeyForJWTTokenGenerationAndValidation2023";
private int expiration = 86400000; // 24 hours in milliseconds
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public Boolean validateToken(String token, String username) {
String tokenUsername = extractUsername(token);
return (tokenUsername.equals(username) && !isTokenExpired(token));
}
public String extractUsername(String token) {
return extractClaims(token).getSubject();
}
private Claims extractClaims(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
}
private Boolean isTokenExpired(String token) {
return extractClaims(token).getExpiration().before(new Date());
}
}
Authentication Controller:
@RestController
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public ResponseEntity createToken(@RequestBody AuthRequest request) throws Exception {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
);
} catch (BadCredentialsException e) {
throw new Exception("Invalid credentials", e);
}
String token = jwtUtil.generateToken(request.getUsername());
return ResponseEntity.ok(new AuthResponse(token));
}
}
JWT Filter:
@Component
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
String authHeader = request.getHeader("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.getUsername())) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
chain.doFilter(request, response);
}
}
Two Minute Drill
- JWT is a stateless authentication token containing user claims.
- Client sends JWT in Authorization: Bearer
header. - JWT has three parts: Header, Payload, Signature.
- Use jjwt library to create and validate tokens.
- Create JWT filter to intercept and validate tokens.
- JWT is perfect for REST APIs and microservices.
Need more clarification?
Drop us an email at career@quipoinfotech.com
