All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.itxiaoer.commons.security.JwtTokenContext Maven / Gradle / Ivy

package com.itxiaoer.commons.security;

import com.itxiaoer.commons.core.util.Md5Utils;
import com.itxiaoer.commons.jwt.JwtAuth;
import com.itxiaoer.commons.jwt.JwtBuilder;
import com.itxiaoer.commons.jwt.JwtProperties;
import com.itxiaoer.commons.jwt.JwtToken;
import com.itxiaoer.commons.security.cache.CacheService;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

/**
 * @author : liuyk
 */
@SuppressWarnings({"unused", "WeakerAccess"})
public class JwtTokenContext {

    private final static String TOKEN_HEAD = "Bearer ";

    @Resource
    private JwtBuilder jwtBuilder;

    @Resource
    private JwtProperties jwtProperties;

    @Resource
    private CacheService cacheService;

    @Resource
    JwtUserDetailService jwtUserDetailService;

    public JwtToken build(JwtAuth userDetails) {
        return jwtBuilder.encode(userDetails);
    }

    public JwtToken refresh(String token) {
        JwtUserDetail jwtUserDetail = jwtUserDetailService.loadUserFromCache(jwtBuilder.get(token, "loginName"), token);
        //判断是否过期
        if (!this.validate(token, jwtUserDetail)) {
            throw new IllegalArgumentException("token is expired.");
        }
        // 将原来旧的token加入黑名单
        String key = jwtProperties.getPrefix() + Md5Utils.digestMD5(token);
        Date expirationDateFromToken = jwtBuilder.expirationDate(token);
        Boolean ifAbsent = cacheService.setIfAbsent(key, new JwtToken(token, expirationDateFromToken.getTime(), Instant.now().toEpochMilli(), JwtToken.Operation.refresh.getValue()));
        if (ifAbsent != null && ifAbsent) {
            //设置过期时间
            cacheService.expireAt(key, expirationDateFromToken);
        }
        // 刷新token的值
        return this.jwtBuilder.refresh(token);
    }


    public String getTokenFromRequest(HttpServletRequest request) {
        String authHeader = request.getHeader(jwtProperties.getHeader());
        String token = this.getTokenFromHeader(authHeader);
        if (StringUtils.isBlank(token)) {
            token = request.getParameter("token");
        }
        return token;
    }

    public String getTokenFromHeader(String authHeader) {
        if (authHeader != null && authHeader.startsWith(TOKEN_HEAD)) {
            return authHeader.substring(TOKEN_HEAD.length());
        }
        return "";
    }


    public Boolean destroy(HttpServletRequest request) {
        String token = this.getTokenFromRequest(request);
        if (StringUtils.isBlank(token)) {
            return true;
        }
        String key = jwtProperties.getPrefix() + Md5Utils.digestMD5(token);
        Date expirationDateFromToken = jwtBuilder.expirationDate(token);
        cacheService.set(key, new JwtToken(token, expirationDateFromToken.getTime(), Instant.now().toEpochMilli(), JwtToken.Operation.destroy.getValue()));
        //设置过期时间
        cacheService.expireAt(key, expirationDateFromToken);
        return true;
    }

    /**
     * 校验token是否合法
     *
     * @param token       token的值
     * @param userDetails 用户信息
     * @return true:合法,false:非法
     */
    public Boolean validate(String token, JwtUserDetail userDetails) {
        if (StringUtils.isBlank(token) || userDetails == null) {
            return false;
        }
        String key = jwtProperties.getPrefix() + Md5Utils.digestMD5(token);
        JwtToken jwtToken = cacheService.get(key);
        // 判断是否在黑名单中
        if (jwtToken != null) {
            //销毁状态
            if (JwtToken.Operation.destroy.getValue() == jwtToken.getType()) {
                return false;
            }

            Long refreshTime = jwtToken.getRefreshTime();
            if (refreshTime != null && jwtToken.getType() == JwtToken.Operation.refresh.getValue()) {
                // 刷新token二分钟内可以使用
                return Instant.now().toEpochMilli() - refreshTime < 1000 * 60 * 2;
            }
        }
        final Instant created = jwtBuilder.createdTime(token);
        final String loginName = jwtBuilder.get(token, "loginName");
        LocalDateTime modifyPasswordTime = userDetails.getModifyPasswordTime();
        if (Objects.isNull(modifyPasswordTime)) {
            return Objects.equals(loginName, userDetails.getUsername())
                    && !jwtBuilder.isExpired(token);
        }
        return Objects.equals(loginName, userDetails.getUsername())
                && !jwtBuilder.isExpired(token) && validate(created, modifyPasswordTime);
    }

    private Boolean validate(Instant created, LocalDateTime lastPasswordReset) {
        return lastPasswordReset == null || created.isAfter(Instant.from(lastPasswordReset));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy