JWTTokenUtil.java
Home
/
sm-shop /
src /
main /
java /
com /
salesmanager /
shop /
store /
security /
JWTTokenUtil.java
package com.salesmanager.shop.store.security;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mobile.device.Device;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import com.salesmanager.shop.store.security.user.JWTUser;
import com.salesmanager.shop.utils.DateUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@Component
public class JWTTokenUtil implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
static final String CLAIM_KEY_USERNAME = "sub";
static final String CLAIM_KEY_AUDIENCE = "aud";
static final String CLAIM_KEY_CREATED = "iat";
static final String AUDIENCE_UNKNOWN = "unknown";
static final String AUDIENCE_WEB = "web";
static final String AUDIENCE_MOBILE = "mobile";
static final String AUDIENCE_TABLET = "tablet";
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
public String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}
public Date getIssuedAtDateFromToken(String token) {
return getClaimFromToken(token, Claims::getIssuedAt);
}
public Date getExpirationDateFromToken(String token) {
return getClaimFromToken(token, Claims::getExpiration);
}
public String getAudienceFromToken(String token) {
return getClaimFromToken(token, Claims::getAudience);
}
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
return claimsResolver.apply(claims);
}
private Claims getAllClaimsFromToken(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}
private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(DateUtil.getDate());
}
private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
return (lastPasswordReset != null && created.before(lastPasswordReset));
}
private String generateAudience(Device device) {
String audience = AUDIENCE_UNKNOWN;
if(device != null) {
if (device.isNormal()) {
audience = AUDIENCE_WEB;
} else if (device.isTablet()) {
audience = AUDIENCE_TABLET;
} else if (device.isMobile()) {
audience = AUDIENCE_MOBILE;
}
}
return audience;
}
private Boolean ignoreTokenExpiration(String token) {
String audience = getAudienceFromToken(token);
return (AUDIENCE_TABLET.equals(audience) || AUDIENCE_MOBILE.equals(audience));
}
public String generateToken(UserDetails userDetails, Device device) {
Map<String, Object> claims = new HashMap<>();
return doGenerateToken(claims, userDetails.getUsername(), generateAudience(device));
}
private String doGenerateToken(Map<String, Object> claims, String subject, String audience) {
final Date createdDate = DateUtil.getDate();
final Date expirationDate = calculateExpirationDate(createdDate);
System.out.println("doGenerateToken " + createdDate);
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setAudience(audience)
.setIssuedAt(createdDate)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
final Date created = getIssuedAtDateFromToken(token);
return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
&& (!isTokenExpired(token) || ignoreTokenExpiration(token));
}
public String refreshToken(String token) {
final Date createdDate = DateUtil.getDate();
final Date expirationDate = calculateExpirationDate(createdDate);
final Claims claims = getAllClaimsFromToken(token);
claims.setIssuedAt(createdDate);
claims.setExpiration(expirationDate);
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean validateToken(String token, UserDetails userDetails) {
JWTUser user = (JWTUser) userDetails;
final String username = getUsernameFromToken(token);
final Date created = getIssuedAtDateFromToken(token);
//final Date expiration = getExpirationDateFromToken(token);
boolean usernameEquals = username.equals(user.getUsername());
boolean isTokenExpired = isTokenExpired(token);
boolean isTokenCreatedBeforeLastPasswordReset = isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate());
return (
usernameEquals && !isTokenExpired && !isTokenCreatedBeforeLastPasswordReset
);
}
private Date calculateExpirationDate(Date createdDate) {
return new Date(createdDate.getTime() + expiration * 1000);
}
}