|
|
package com.ils.oms.utils;
|
|
|
|
|
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.exceptions.ValidateException;
|
|
|
import cn.hutool.core.lang.TypeReference;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.crypto.SecureUtil;
|
|
|
import cn.hutool.json.JSONObject;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import cn.hutool.jwt.JWT;
|
|
|
import cn.hutool.jwt.JWTPayload;
|
|
|
import cn.hutool.jwt.RegisteredPayload;
|
|
|
import cn.hutool.jwt.signers.JWTSigner;
|
|
|
import cn.hutool.jwt.signers.JWTSignerUtil;
|
|
|
import com.ils.oms.result.JwtVerifyResult;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
|
|
|
@Slf4j
|
|
|
@Component
|
|
|
public class JwtUtil {
|
|
|
private static final JWTSigner jwtSigner = JWTSignerUtil.hs256("!34ADAS3ddfdssdfhii@#$$@#efh3".getBytes());
|
|
|
private static final String AUTH_TOKEN_KEY = "ils";
|
|
|
|
|
|
private static final String APP_KEY = "ilsTestKey2023";
|
|
|
private static final String APP_SECRET = "ilsTestKey2023";
|
|
|
public static void main(String[] args) {
|
|
|
Map<String,String> payload = new HashMap<>();
|
|
|
payload.put("userName","ilsadmin");
|
|
|
payload.put("passWord", "123456");
|
|
|
String token = createToken(payload);
|
|
|
log.info("token: {}",token );
|
|
|
|
|
|
JwtVerifyResult jwtVerifyResult = validateToken(token);
|
|
|
if(jwtVerifyResult.getSuccess()){
|
|
|
payload = jwtVerifyResult.getPayload();
|
|
|
log.info("userName: {}, passWord: {}", payload.get("userName"), payload.get("passWord"));
|
|
|
}else{
|
|
|
log.error("验证失败:"+jwtVerifyResult.toString());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 生成安全的 jwt token
|
|
|
* @param payload jwt负载
|
|
|
* @return
|
|
|
*/
|
|
|
public static String createToken(Map<String, String> payload) {
|
|
|
Date dateNow = new Date();
|
|
|
String authToken = SecureUtil.md5(SecureUtil.sha256(APP_KEY + "_" + DateUtil.formatDateTime(dateNow) + "_" + APP_SECRET));
|
|
|
payload.put(AUTH_TOKEN_KEY, authToken);
|
|
|
return JWT.create()
|
|
|
.addPayloads(payload)
|
|
|
.setIssuedAt(dateNow)
|
|
|
.setExpiresAt(DateUtil.endOfDay(dateNow))
|
|
|
.sign(jwtSigner);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* jwt 验证,1)hash256签名,2)失效时间,3)自定义二重安全校验
|
|
|
* @param token 生成的jwt token
|
|
|
* @return map :当error = "ok",会额外多出 payload
|
|
|
*/
|
|
|
public static JwtVerifyResult validateToken(String token) {
|
|
|
|
|
|
try {
|
|
|
JWT jwt = JWT.of(token);
|
|
|
jwt.setSigner(jwtSigner);
|
|
|
|
|
|
//1.验证hash256签名
|
|
|
Boolean hs256Bool = jwt.verify();
|
|
|
if (!hs256Bool) {
|
|
|
return new JwtVerifyResult(false, "hash256签名校验失败");
|
|
|
}
|
|
|
//2.验证签名的时间,单位s
|
|
|
Boolean validateBool = jwt.validate(60*60*24);
|
|
|
if (!validateBool) {
|
|
|
return new JwtVerifyResult(false, "时间负载校验失败");
|
|
|
}
|
|
|
//3.获取二重 authToken 认证校验
|
|
|
JWTPayload jwtPayload = jwt.getPayload();
|
|
|
Date subAtDate = jwtPayload.getClaimsJson().getDate(RegisteredPayload.ISSUED_AT);
|
|
|
|
|
|
String atScource = String.valueOf(jwtPayload.getClaim(AUTH_TOKEN_KEY));
|
|
|
String authToken = SecureUtil.md5(SecureUtil.sha256(APP_KEY + "_" +DateUtil.formatDateTime(subAtDate) + "_" + APP_SECRET));
|
|
|
|
|
|
if (StrUtil.isEmpty(atScource) || !atScource.equals(authToken)) {
|
|
|
return new JwtVerifyResult(false, "二重身份认证校验失败");
|
|
|
}
|
|
|
|
|
|
//4.将负载参数转换成map返回
|
|
|
JSONObject payloadJson = jwtPayload.getClaimsJson();
|
|
|
payloadJson.remove(AUTH_TOKEN_KEY);
|
|
|
JwtVerifyResult jwtVerifyResult = new JwtVerifyResult(true, "签名有效");
|
|
|
jwtVerifyResult.setPayload(JSONUtil.toBean(payloadJson, new TypeReference<Map<String, String>>() {
|
|
|
}, true));
|
|
|
return jwtVerifyResult;
|
|
|
|
|
|
} catch (ValidateException e) {
|
|
|
return new JwtVerifyResult(true, "无效的签名");
|
|
|
}
|
|
|
}
|
|
|
}
|