feat: API 参数签名配置支持自定义摘要算法

This commit is contained in:
click33 2025-03-09 19:44:45 +08:00
parent abc2b0be69
commit 1c4af4cc03
4 changed files with 103 additions and 30 deletions

View File

@ -15,6 +15,10 @@
*/
package cn.dev33.satoken.config;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.fun.SaParamRetFunction;
import cn.dev33.satoken.secure.SaSecureUtil;
/**
* Sa-Token API 接口签名/验签 相关配置类
*
@ -36,6 +40,10 @@ public class SaSignConfig {
*/
private long timestampDisparity = 1000 * 60 * 15;
/**
* fullStr 的摘要算法
*/
private String digestAlgo = "md5";
public SaSignConfig() {
}
@ -48,6 +56,70 @@ public class SaSignConfig {
this.secretKey = secretKey;
}
// -------------- 扩展方法
/**
* 计算保存 nonce 时应该使用的 ttl单位
* @return /
*/
public long getSaveNonceExpire() {
// 如果 timestampDisparity >= 0 nonceTtl 的值等于 timestampDisparity 的值单位转秒
if(timestampDisparity >= 0) {
return timestampDisparity / 1000;
}
// 否则nonceTtl 的值为 24 小时
else {
return 60 * 60 * 24;
}
}
// -------------- 策略函数
/**
* fullStr 的摘要算法函数
*/
public SaParamRetFunction<String, String> digestMethod = (fullStr) -> {
// md5
if(digestAlgo.equalsIgnoreCase("md5")) {
return SaSecureUtil.md5(fullStr);
}
// sha1
if(digestAlgo.equalsIgnoreCase("sha1")) {
return SaSecureUtil.sha1(fullStr);
}
// sha256
if(digestAlgo.equalsIgnoreCase("sha256")) {
return SaSecureUtil.sha256(fullStr);
}
// sha384
if(digestAlgo.equalsIgnoreCase("sha384")) {
return SaSecureUtil.sha384(fullStr);
}
// sha512
if(digestAlgo.equalsIgnoreCase("sha512")) {
return SaSecureUtil.sha512(fullStr);
}
// 未知
throw new SaTokenException("不支持的摘要算法:" + digestAlgo + ",你可以自定义摘要算法函数实现");
};
/**
* 设置: fullStr 的摘要算法函数
*
* @param digestMethod /
* @return 对象自身
*/
public SaSignConfig setDigestMethod(SaParamRetFunction<String, String> digestMethod) {
this.digestMethod = digestMethod;
return this;
}
// -------------- get/set
/**
* 获取 API 调用签名秘钥
*
@ -95,18 +167,22 @@ public class SaSignConfig {
}
/**
* 计算保存 nonce 时应该使用的 ttl单位
* 获取 fullStr 的摘要算法
*
* @return digestAlgo fullStr 的摘要算法
*/
public String getDigestAlgo() {
return this.digestAlgo;
}
/**
* 设置 fullStr 的摘要算法
* @param digestAlgo /
* @return /
*/
public long getSaveNonceExpire() {
// 如果 timestampDisparity >= 0 nonceTtl 的值等于 timestampDisparity 的值单位转秒
if(timestampDisparity >= 0) {
return timestampDisparity / 1000;
}
// 否则nonceTtl 的值为 24 小时
else {
return 60 * 60 * 24;
}
public SaSignConfig setDigestAlgo(String digestAlgo) {
this.digestAlgo = digestAlgo;
return this;
}
@Override
@ -117,15 +193,4 @@ public class SaSignConfig {
+ "]";
}
/**
* 设置是否校验 nonce 随机字符串
* <h2> isCheckNonce 方案已废弃不再提供此配置项 </h2>
*
* @param isCheckNonce /
*/
@Deprecated
public void setIsCheckNonce(Boolean isCheckNonce) {
System.err.println("--------- isCheckNonce 方案已废弃,不再提供此配置项 ---------");
}
}

View File

@ -20,7 +20,6 @@ import cn.dev33.satoken.config.SaSignConfig;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaSignException;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import java.util.Map;
@ -173,7 +172,7 @@ public class SaSignTemplate {
// 计算签名
String paramsStr = joinParamsDictSort(paramsMap);
String fullStr = paramsStr + "&" + key + "=" + secretKey;
String signStr = abstractStr(fullStr);
String signStr = digestFullStr(fullStr);
// 输入日志方便调试
log.debug("fullStr{}", fullStr);
@ -188,8 +187,8 @@ public class SaSignTemplate {
* @param fullStr 待摘要的字符串
* @return 签名
*/
public String abstractStr(String fullStr) {
return SaSecureUtil.md5(fullStr);
public String digestFullStr(String fullStr) {
return getSignConfigOrGlobal().digestMethod.run(fullStr);
}
/**
@ -281,7 +280,7 @@ public class SaSignTemplate {
}
/**
* 判断给定的参数 + 秘钥 生成的签名是否为有效签名
* 判断给定的参数 生成的签名是否为有效签名
* @param paramsMap 参数列表
* @param sign 待验证的签名
* @return 签名是否有效
@ -292,7 +291,7 @@ public class SaSignTemplate {
}
/**
* 校验给定的参数 + 秘钥 生成的签名是否为有效签名如果签名无效则抛出异常
* 校验给定的参数 生成的签名是否为有效签名如果签名无效则抛出异常
* @param paramsMap 参数列表
* @param sign 待验证的签名
*/
@ -349,6 +348,9 @@ public class SaSignTemplate {
// 通过
}
// ----------- Web 请求相关 封装
/**
* 判断一个请求中的 noncetimestampsign 是否均为合法的
* @param request 待校验的请求对象
@ -382,7 +384,7 @@ public class SaSignTemplate {
* @param paramNames 指定的参数名称不可为空如果传入空数组则代表只拿 timestampnoncesign 三个参数
* @return 提取出的参数
*/
public Map<String, String> takeRequestParam(SaRequest request, String [] paramNames) {
protected Map<String, String> takeRequestParam(SaRequest request, String [] paramNames) {
Map<String, String> paramMap = new TreeMap<>();
// 此三个参数是必须获取的

View File

@ -119,7 +119,7 @@ public class SaSignUtil {
}
/**
* 判断给定的参数 + 秘钥 生成的签名是否为有效签名
* 判断给定的参数 生成的签名是否为有效签名
* @param paramsMap 参数列表
* @param sign 待验证的签名
* @return 签名是否有效
@ -129,7 +129,7 @@ public class SaSignUtil {
}
/**
* 校验给定的参数 + 秘钥 生成的签名是否为有效签名如果签名无效则抛出异常
* 校验给定的参数 生成的签名是否为有效签名如果签名无效则抛出异常
* @param paramsMap 参数列表
* @param sign 待验证的签名
*/
@ -154,6 +154,9 @@ public class SaSignUtil {
SaManager.getSaSignTemplate().checkParamMap(paramMap);
}
// ----------- Web 请求相关 封装
/**
* 判断一个请求中的 noncetimestampsign 是否均为合法的
* @param request 待校验的请求对象

View File

@ -18,6 +18,9 @@ sa-token:
token-style: uuid
# 是否输出操作日志
is-log: true
sign:
# token签名密钥
secret-key: abc123
spring:
# redis配置