|
@@ -10,9 +10,7 @@ import org.springframework.security.core.GrantedAuthority;
|
|
|
import org.springframework.security.core.userdetails.UserDetails;
|
|
import org.springframework.security.core.userdetails.UserDetails;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
-import java.util.Date;
|
|
|
|
|
-import java.util.HashMap;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
|
|
+import java.util.*;
|
|
|
import java.util.function.Function;
|
|
import java.util.function.Function;
|
|
|
|
|
|
|
|
import static java.lang.System.currentTimeMillis;
|
|
import static java.lang.System.currentTimeMillis;
|
|
@@ -25,6 +23,15 @@ public class JwtService {
|
|
|
@Value("${jwt.secret}")
|
|
@Value("${jwt.secret}")
|
|
|
private String secret;
|
|
private String secret;
|
|
|
|
|
|
|
|
|
|
+ private static final Map<String, Long> ROLE_EXPIRATION_HOURS = Map.of(
|
|
|
|
|
+ "ADMIN", 1L,
|
|
|
|
|
+ "SERVICE", 12L,
|
|
|
|
|
+ "VPN", 24L,
|
|
|
|
|
+ "USER", 48L
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ private static final List<String> ROLE_PRIORITY = List.of("ADMIN", "SERVICE", "VPN");
|
|
|
|
|
+
|
|
|
public String extractUsername(String token) {
|
|
public String extractUsername(String token) {
|
|
|
return extractClaim(token, Claims::getSubject);
|
|
return extractClaim(token, Claims::getSubject);
|
|
|
}
|
|
}
|
|
@@ -41,9 +48,9 @@ public class JwtService {
|
|
|
public Authentication generateToken(UserDetails userDetails) {
|
|
public Authentication generateToken(UserDetails userDetails) {
|
|
|
Map<String, Object> claims = new HashMap<>();
|
|
Map<String, Object> claims = new HashMap<>();
|
|
|
claims.put(
|
|
claims.put(
|
|
|
- "authorities", userDetails.getAuthorities().stream()
|
|
|
|
|
- .map(GrantedAuthority::getAuthority)
|
|
|
|
|
- .collect(toSet())
|
|
|
|
|
|
|
+ "authorities", userDetails.getAuthorities().stream()
|
|
|
|
|
+ .map(GrantedAuthority::getAuthority)
|
|
|
|
|
+ .collect(toSet())
|
|
|
);
|
|
);
|
|
|
return generateToken(claims, userDetails);
|
|
return generateToken(claims, userDetails);
|
|
|
}
|
|
}
|
|
@@ -58,30 +65,41 @@ public class JwtService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private Authentication generateToken(Map<String, Object> claims, UserDetails userDetails) {
|
|
private Authentication generateToken(Map<String, Object> claims, UserDetails userDetails) {
|
|
|
- Date expirationDate = new Date(currentTimeMillis() + 1000 * 60 * 60 * 48);
|
|
|
|
|
|
|
+ Date expirationDate = new Date(currentTimeMillis() + 1000 * 60 * 60 * hoursByRole(claims));
|
|
|
String token = Jwts.builder().setClaims(claims)
|
|
String token = Jwts.builder().setClaims(claims)
|
|
|
- .setSubject(userDetails.getUsername())
|
|
|
|
|
- .setIssuedAt(new Date(currentTimeMillis()))
|
|
|
|
|
- .setExpiration(expirationDate)
|
|
|
|
|
- .signWith(SignatureAlgorithm.HS256, secret).compact();
|
|
|
|
|
|
|
+ .setSubject(userDetails.getUsername())
|
|
|
|
|
+ .setIssuedAt(new Date(currentTimeMillis()))
|
|
|
|
|
+ .setExpiration(expirationDate)
|
|
|
|
|
+ .signWith(SignatureAlgorithm.HS256, secret).compact();
|
|
|
|
|
|
|
|
return new Authentication(token,
|
|
return new Authentication(token,
|
|
|
- expirationDate.toInstant(),
|
|
|
|
|
- userDetails.getUsername(),
|
|
|
|
|
- userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).toList()
|
|
|
|
|
|
|
+ expirationDate.toInstant(),
|
|
|
|
|
+ userDetails.getUsername(),
|
|
|
|
|
+ userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).toList()
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private Claims extractAllClaims(String token) {
|
|
private Claims extractAllClaims(String token) {
|
|
|
try {
|
|
try {
|
|
|
return Jwts.parser()
|
|
return Jwts.parser()
|
|
|
- .setSigningKey(secret)
|
|
|
|
|
- .parseClaimsJws(token)
|
|
|
|
|
- .getBody();
|
|
|
|
|
|
|
+ .setSigningKey(secret)
|
|
|
|
|
+ .parseClaimsJws(token)
|
|
|
|
|
+ .getBody();
|
|
|
} catch (ExpiredJwtException e) {
|
|
} catch (ExpiredJwtException e) {
|
|
|
log.warn("Expired JWT token [{}]", e.getClaims());
|
|
log.warn("Expired JWT token [{}]", e.getClaims());
|
|
|
return e.getClaims();
|
|
return e.getClaims();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private long hoursByRole(Map<String, Object> claims) {
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ Set<String> authorities = (Set<String>) claims.get("authorities");
|
|
|
|
|
+
|
|
|
|
|
+ return ROLE_PRIORITY.stream()
|
|
|
|
|
+ .filter(authorities::contains)
|
|
|
|
|
+ .findFirst()
|
|
|
|
|
+ .map(ROLE_EXPIRATION_HOURS::get)
|
|
|
|
|
+ .orElse(48L);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|