You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
4.1 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 验证1hash256签名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, "无效的签名");
}
}
}