JSON Web Tokens (JWT) are an open standard for securely transmitting information between parties as a JSON object.
header.payload.signature
Header: { "alg": "HS256", "typ": "JWT" } Payload: { "sub": "123", "name": "John", "iat": 1516239022 } Signature: HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
text
<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>@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}public class JwtTokenUtil {
private final String SECRET_KEY = "your-secret-key";
private final long EXPIRATION_TIME = 864_000_000; // 10 days
public String generateToken(UserDetails userDetails) {
return Jwts.builder()
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public Boolean validateToken(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
}- Client sends credentials to
/login - Server validates credentials
- Server generates JWT and returns it
- Client includes JWT in
Authorization: Bearer <token>header - Server validates JWT on each request
-
Token Storage:
- Use HttpOnly cookies for web apps
- Secure storage for mobile apps
-
Token Expiration:
- Short-lived access tokens (15-30 mins)
- Long-lived refresh tokens (7-30 days)
-
Secret Management:
- Never hardcode secrets
- Use environment variables or secret management tools
-
Additional Security:
- Implement IP whitelisting
- Add device fingerprinting
- Use token blacklisting for logout
-
None Algorithm Vulnerability:
- Always validate the algorithm in your JWT parser
-
Secret Bruteforcing:
- Use strong secrets (minimum 32 characters)
-
Token Sidejacking:
- Implement CSRF protection
- Use strict CORS policies
-
Information Exposure:
- Don't store sensitive data in JWTs
public class RefreshToken {
private String token;
private Date expiryDate;
// Getters and setters
}
@Service
public class AuthService {
public AuthResponse refreshToken(String refreshToken) {
// Validate refresh token
// Generate new access token
// Optionally generate new refresh token
}
}-
Standard Claims:
sub(subject): User IDiat(issued at): Token creation timeexp(expiration): Token expiration time
-
Custom Claims:
roles: User roles/permissionstenant: For multi-tenant appsiss: Token issuer