package com.ikm.xmanager.jwt; import com.ikm.xmanager.cms.model.User; import com.ikm.xmanager.jwt.common.utils.TimeProvider; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mobile.device.Device; import org.springframework.stereotype.Component; import java.io.Serializable; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created by Tom Chen on 2017/7/20. * jwt工具类 */ @Component public class JwtTokenUtil implements Serializable { private static final long serialVersionUID = -3301605591108950415L; static final String CLAIM_KEY_USERNAME = "sub"; static final String CLAIM_KEY_AUDIENCE = "audience"; static final String CLAIM_KEY_CREATED = "created"; static final String CLAIM_KEY_EXPIRED = "exp"; static final String AUDIENCE_UNKNOWN = "unknown"; static final String AUDIENCE_WEB = "web"; static final String AUDIENCE_MOBILE = "mobile"; static final String AUDIENCE_TABLET = "tablet"; @Autowired private TimeProvider timeProvider; @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; public String getUsernameFromToken(String token) { String username; try { final Claims claims = getClaimsFromToken(token); username = claims.getSubject(); } catch (Exception e) { username = null; } return username; } public Date getCreatedDateFromToken(String token) { Date created; try { final Claims claims = getClaimsFromToken(token); created = new Date((Long) claims.get(CLAIM_KEY_CREATED)); } catch (Exception e) { created = null; } return created; } public Date getExpirationDateFromToken(String token) { Date expiration; try { final Claims claims = getClaimsFromToken(token); expiration = claims.getExpiration(); } catch (Exception e) { expiration = null; } return expiration; } public String getAudienceFromToken(String token) { String audience; try { final Claims claims = getClaimsFromToken(token); audience = (String) claims.get(CLAIM_KEY_AUDIENCE); } catch (Exception e) { audience = null; } return audience; } private Claims getClaimsFromToken(String token) { Claims claims; try { claims = Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); } catch (Exception e) { claims = null; } return claims; } private Boolean isTokenExpired(String token) { final Date expiration = getExpirationDateFromToken(token); return expiration.before(timeProvider.now()); } private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) { return (lastPasswordReset != null && created.before(lastPasswordReset)); } private String generateAudience(Device device) { String audience = AUDIENCE_UNKNOWN; 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(User user, Device device) { Map<String, Object> claims = new HashMap<>(); claims.put(CLAIM_KEY_USERNAME, user.getLoginName()); claims.put(CLAIM_KEY_AUDIENCE, generateAudience(device)); final Date createdDate = timeProvider.now(); claims.put(CLAIM_KEY_CREATED, createdDate); return doGenerateToken(claims); } private String doGenerateToken(Map<String, Object> claims) { final Date createdDate = (Date) claims.get(CLAIM_KEY_CREATED); final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000); System.out.println("doGenerateToken " + createdDate); return Jwts.builder() .setClaims(claims) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512, secret) .compact(); } public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) { final Date created = getCreatedDateFromToken(token); return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset) && (!isTokenExpired(token) || ignoreTokenExpiration(token)); } public String refreshToken(String token) { String refreshedToken; try { final Claims claims = getClaimsFromToken(token); claims.put(CLAIM_KEY_CREATED, timeProvider.now()); refreshedToken = doGenerateToken(claims); } catch (Exception e) { refreshedToken = null; } return refreshedToken; } public Boolean validateToken(String token, User user) { User jwtUser = user; final String username = getUsernameFromToken(token); final Date created = getCreatedDateFromToken(token); //final Date expiration = getExpirationDateFromToken(token); return ( username.equals(user.getLoginName()) && !isTokenExpired(token) && !isCreatedBeforeLastPasswordReset(created, user.getCreateTime())); } }