bilhej/backend/src/main/java/se/bilhalsning/security/JwtService.java
Joakim Mörling 8a95483fb8 feat: add admin role support to backend JWT authentication
Add role-based access control to the backend authentication system. The User
entity now carries a role field (default 'user'), JWT tokens include a 'role'
claim, and the login endpoint populates it from the database.

Changes:
- User entity: add role column (VARCHAR(20), default 'user') with getter/setter
- JwtService: add generateToken(email, role) overload and extractRole(token)
- AuthController: pass user.getRole() on login, 'user' on register
- Flyway V3: ALTER TABLE users ADD COLUMN role
- Flyway V4: seed admin user (admin@bilhalsning.se, role='admin')
- AuthControllerTest: add tests for admin role in token, role from DB on login
- JwtServiceTest: add tests for role extraction and default role
- UserServiceTest: assert role defaults to 'user' on createUser
2026-05-14 12:38:55 +02:00

71 lines
2 KiB
Java

package se.bilhalsning.security;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class JwtService {
private static final long DEFAULT_EXPIRATION_MS = 86_400_000;
private final SecretKey secretKey;
private final long expirationMs;
public JwtService(String secret) {
this(secret, DEFAULT_EXPIRATION_MS);
}
JwtService(String secret, long expirationMs) {
this.secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
this.expirationMs = expirationMs;
}
public String generateToken(String email) {
return generateToken(email, "user");
}
public String generateToken(String email, String role) {
return Jwts.builder()
.subject(email)
.claim("role", role)
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + expirationMs))
.signWith(secretKey)
.compact();
}
public String extractUsername(String token) {
return Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(token)
.getPayload()
.getSubject();
}
public String extractRole(String token) {
return Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(token)
.getPayload()
.get("role", String.class);
}
public boolean isTokenValid(String token) {
try {
Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(token);
return true;
} catch (ExpiredJwtException e) {
return false;
} catch (Exception e) {
return false;
}
}
}