JwtTokenUtil.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package com.izouma.awesomeAdmin.security;
  2. import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  3. import io.jsonwebtoken.Claims;
  4. import io.jsonwebtoken.Clock;
  5. import io.jsonwebtoken.Jwts;
  6. import io.jsonwebtoken.SignatureAlgorithm;
  7. import io.jsonwebtoken.impl.DefaultClock;
  8. import lombok.AllArgsConstructor;
  9. import org.apache.commons.lang3.StringUtils;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.beans.factory.annotation.Value;
  12. import org.springframework.cache.Cache;
  13. import org.springframework.cache.CacheManager;
  14. import org.springframework.security.core.userdetails.UserDetails;
  15. import org.springframework.stereotype.Component;
  16. import java.io.Serializable;
  17. import java.util.Date;
  18. import java.util.HashMap;
  19. import java.util.Map;
  20. import java.util.function.Function;
  21. @Component
  22. public class JwtTokenUtil implements Serializable {
  23. private static final long serialVersionUID = -3301605591108950415L;
  24. static final String CLAIM_KEY_USERNAME = "sub";
  25. static final String CLAIM_KEY_CREATED = "iat";
  26. @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "It's okay here")
  27. private Clock clock = DefaultClock.INSTANCE;
  28. private JwtConfig jwtConfig;
  29. public JwtTokenUtil(JwtConfig jwtConfig) {
  30. this.jwtConfig = jwtConfig;
  31. }
  32. public String getUsernameFromToken(String token) {
  33. return getClaimFromToken(token, Claims::getSubject);
  34. }
  35. public Date getIssuedAtDateFromToken(String token) {
  36. return getClaimFromToken(token, Claims::getIssuedAt);
  37. }
  38. public Date getExpirationDateFromToken(String token) {
  39. return getClaimFromToken(token, Claims::getExpiration);
  40. }
  41. public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
  42. final Claims claims = getAllClaimsFromToken(token);
  43. return claimsResolver.apply(claims);
  44. }
  45. private Claims getAllClaimsFromToken(String token) {
  46. return Jwts.parser()
  47. .setSigningKey(jwtConfig.getSecret())
  48. .parseClaimsJws(token)
  49. .getBody();
  50. }
  51. private Boolean isTokenExpired(String token) {
  52. final Date expiration = getExpirationDateFromToken(token);
  53. return expiration.before(clock.now());
  54. }
  55. private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
  56. return (lastPasswordReset != null && created.before(lastPasswordReset));
  57. }
  58. private Boolean ignoreTokenExpiration(String token) {
  59. // here you specify tokens, for that the expiration is ignored
  60. return false;
  61. }
  62. public String generateToken(UserDetails userDetails) {
  63. Map<String, Object> claims = new HashMap<>();
  64. return doGenerateToken(claims, userDetails.getUsername());
  65. }
  66. private String doGenerateToken(Map<String, Object> claims, String subject) {
  67. final Date createdDate = clock.now();
  68. final Date expirationDate = calculateExpirationDate(createdDate);
  69. return Jwts.builder()
  70. .setClaims(claims)
  71. .setSubject(subject)
  72. .setIssuedAt(createdDate)
  73. .setExpiration(expirationDate)
  74. .signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret())
  75. .compact();
  76. }
  77. public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
  78. final Date created = getIssuedAtDateFromToken(token);
  79. return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
  80. && (!isTokenExpired(token) || ignoreTokenExpiration(token));
  81. }
  82. public String refreshToken(String token) {
  83. final Date createdDate = clock.now();
  84. final Date expirationDate = calculateExpirationDate(createdDate);
  85. final Claims claims = getAllClaimsFromToken(token);
  86. claims.setIssuedAt(createdDate);
  87. claims.setExpiration(expirationDate);
  88. return Jwts.builder()
  89. .setClaims(claims)
  90. .signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret())
  91. .compact();
  92. }
  93. public Boolean validateToken(String token, UserDetails userDetails) {
  94. JwtUser user = (JwtUser) userDetails;
  95. final String username = getUsernameFromToken(token);
  96. final Date created = getIssuedAtDateFromToken(token);
  97. //final Date expiration = getExpirationDateFromToken(token);
  98. return (
  99. username.equals(user.getUsername())
  100. && !isTokenExpired(token)
  101. && !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate())
  102. );
  103. }
  104. private Date calculateExpirationDate(Date createdDate) {
  105. return new Date(createdDate.getTime() + jwtConfig.getExpiration() * 1000);
  106. }
  107. }