Authorization and Authentication in Java: Spring Security and JWT
Organizing secure access to resources is one of the key tasks when developing web applications in Java. In this article, we will break down two fundamental concepts: authentication (verifying user identity) and authorization (verifying access rights). We will look at practical examples using the popular framework Spring Security and the JSON Web Tokens (JWT) technology.
1. Basic Concepts
Before moving on to the code, it is important to clearly distinguish the terms:
- Authentication — the process of verifying who the user is. Usually done via login and password, biometrics, or tokens.
- Authorization — the process of determining what the user is allowed to do. For example, access to specific API endpoints or application features.
In modern Java applications, the Spring Security + JWT combination is most often used to implement these mechanisms. JWT allows storing user information in a compact token that can be easily transferred between the client and server.
2. Configuring Spring Security with JWT
Let's add the necessary dependencies to pom.xml (Maven):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId></dependency><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.12.3</version></dependency><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.12.3</version> <scope>runtime</scope></dependency><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.12.3</version> <scope>runtime</scope></dependency>3. Creating a Service for Working with JWT
Let's create a JwtService class that will be responsible for generating and validating tokens:
import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import io.jsonwebtoken.security.Keys;import org.springframework.stereotype.Service;
import javax.crypto.SecretKey;import java.util.Date;import java.util.HashMap;import java.util.Map;
@Servicepublic class JwtService {
private final SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256); private final long expirationMs = 86400000; // 24 hours
public String generateToken(String username) { Map<String, Object> claims = new HashMap<>(); return Jwts.builder() .setClaims(claims) .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + expirationMs)) .signWith(secretKey) .compact(); }
public String extractUsername(String token) { return extractAllClaims(token).getSubject(); }
private Claims extractAllClaims(String token) { return Jwts.parserBuilder() .setSigningKey(secretKey) .build() .parseClaimsJws(token) .getBody(); }
public boolean isTokenValid(String token, String username) { final String extractedUsername = extractUsername(token); return (extractedUsername.equals(username) && !isTokenExpired(token)); }
private boolean isTokenExpired(String token) { return extractAllClaims(token).getExpiration().befo