diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckSign.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckSign.java
index 7df9d495..45f0eecc 100644
--- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckSign.java
+++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckSign.java
@@ -32,6 +32,14 @@ import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface SaCheckSign {
+ /**
+ * 多实例下的 appid 值,用于区分不同的实例,如不填写则代表使用全局默认实例
+ * 允许以 #{} 的形式指定为请求参数,如:#{appid}
+ *
+ * @return /
+ */
+ String appid() default "";
+
/**
* 指定参与签名的参数有哪些,如果不填写则默认为全部参数
*
diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckSignHandler.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckSignHandler.java
index e804f75b..67f1c729 100644
--- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckSignHandler.java
+++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckSignHandler.java
@@ -17,7 +17,8 @@ package cn.dev33.satoken.annotation.handler;
import cn.dev33.satoken.annotation.SaCheckSign;
import cn.dev33.satoken.context.SaHolder;
-import cn.dev33.satoken.sign.SaSignUtil;
+import cn.dev33.satoken.context.model.SaRequest;
+import cn.dev33.satoken.sign.SaSignMany;
import java.lang.reflect.Method;
@@ -36,11 +37,17 @@ public class SaCheckSignHandler implements SaAnnotationHandlerInterface signMany = new LinkedHashMap<>();
+
/**
* @return token 名称 (同时也是: cookie 名称、提交 token 时参数的名称、存储 token 时的 key 前缀)
@@ -695,6 +702,25 @@ public class SaTokenConfig implements Serializable {
return this;
}
+ /**
+ * 获取 API 签名配置 多实例
+ *
+ * @return /
+ */
+ public Map getSignMany() {
+ return this.signMany;
+ }
+
+ /**
+ * 设置 API 签名配置 多实例
+ *
+ * @param signMany /
+ * @return /
+ */
+ public SaTokenConfig setSignMany(Map signMany) {
+ this.signMany = signMany;
+ return this;
+ }
@Override
public String toString() {
return "SaTokenConfig ["
@@ -729,6 +755,7 @@ public class SaTokenConfig implements Serializable {
+ ", checkSameToken=" + checkSameToken
+ ", cookie=" + cookie
+ ", sign=" + sign
+ + ", signMany=" + signMany
+ "]";
}
diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java b/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java
index 5449d952..fd76ff53 100644
--- a/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java
+++ b/sa-token-core/src/main/java/cn/dev33/satoken/error/SaErrorCode.java
@@ -198,4 +198,7 @@ public interface SaErrorCode {
/** timestamp 超出允许的范围 */
int CODE_12203 = 12203;
+ /** 未找到对应 appid 的 SaSignConfig */
+ int CODE_12211 = 12211;
+
}
diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignMany.java b/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignMany.java
new file mode 100644
index 00000000..0bf39de6
--- /dev/null
+++ b/sa-token-core/src/main/java/cn/dev33/satoken/sign/SaSignMany.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020-2099 sa-token.cc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.dev33.satoken.sign;
+
+import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.config.SaSignConfig;
+import cn.dev33.satoken.error.SaErrorCode;
+import cn.dev33.satoken.exception.SaSignException;
+import cn.dev33.satoken.fun.SaParamRetFunction;
+import cn.dev33.satoken.util.SaFoxUtil;
+
+/**
+ * API 参数签名算法 - 多实例总控类
+ *
+ * @author click33
+ * @since 1.41.0
+ */
+public class SaSignMany {
+
+ /**
+ * 根据 appid 获取 SaSignConfig,允许自定义
+ */
+ public static SaParamRetFunction findSaSignConfigMethod = (appid) -> {
+ return SaManager.getConfig().getSignMany().get(appid);
+ };
+
+ /**
+ * 获取 SaSignTemplate,根据 appid
+ * @param appid /
+ * @return /
+ */
+ public static SaSignTemplate getSignTemplate(String appid) {
+
+ // appid 为空,返回全局默认 SaSignTemplate
+ if(SaFoxUtil.isEmpty(appid)){
+ return SaManager.getSaSignTemplate();
+ }
+
+ // 获取 SaSignConfig
+ SaSignConfig config = findSaSignConfigMethod.run(appid);
+ if(config == null){
+ throw new SaSignException("未找到签名配置,appid=" + appid).setCode(SaErrorCode.CODE_12211);
+ }
+
+ // 创建 SaSignTemplate 并返回
+ return new SaSignTemplate(config);
+ }
+
+}
diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java
index ab85a14f..6a0a4397 100644
--- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java
+++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java
@@ -1,6 +1,7 @@
package com.pj.test;
import cn.dev33.satoken.annotation.SaCheckHttpDigest;
+import cn.dev33.satoken.annotation.SaCheckSign;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.spring.SpringMVCUtil;
import cn.dev33.satoken.stp.SaLoginParameter;
@@ -40,6 +41,7 @@ public class TestController {
// 测试 浏览器访问: http://localhost:8081/test/test
@RequestMapping("test")
+ @SaCheckSign(appid = "#{appid}", verifyParams = {"name", "age"})
public SaResult test() {
System.out.println("------------进来了 " + SaFoxUtil.formatDate(new Date()));
// StpUtil.getLoginId();
diff --git a/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml
index e9416043..e93f2b88 100644
--- a/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml
+++ b/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml
@@ -21,6 +21,9 @@ sa-token:
sign:
# token签名密钥
secret-key: abc123
+ sign-many:
+ 10001:
+ secret-key: 123456
spring:
# redis配置