From 4702d8ed7437a3369acb7bd3a37e35bfef7c690f Mon Sep 17 00:00:00 2001
From: diaohang <4831703@qq.com>
Date: Sun, 27 Apr 2025 16:12:00 +0800
Subject: [PATCH] =?UTF-8?q?refactor(signature):=20=E9=87=8D=E6=9E=84?=
=?UTF-8?q?=E4=BA=86=E8=8E=B7=E5=8F=96=20appSecret=20=E7=9A=84=E6=96=B9?=
=?UTF-8?q?=E5=BC=8F=EF=BC=8C=E5=BC=95=E5=85=A5=E4=BA=86=20ApiSignatureSec?=
=?UTF-8?q?retFetcher=20=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=85=81=E8=AE=B8?=
=?UTF-8?q?=E4=B8=8D=E5=90=8C=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E8=8E=B7=E5=8F=96=20appSecret=20=E7=9A=84=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../YudaoApiSignatureAutoConfiguration.java | 15 ++++++++++++---
.../signature/core/aop/ApiSignatureAspect.java | 4 +++-
.../fetcher/ApiSignatureSecretFetcher.java | 18 ++++++++++++++++++
.../DefaultApiSignatureSecretFetcherImpl.java | 18 ++++++++++++++++++
.../signature/core/ApiSignatureTest.java | 13 +++++++++----
5 files changed, 60 insertions(+), 8 deletions(-)
create mode 100644 yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/ApiSignatureSecretFetcher.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/DefaultApiSignatureSecretFetcherImpl.java
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/config/YudaoApiSignatureAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/config/YudaoApiSignatureAutoConfiguration.java
index 7c6842408..8dc61a816 100644
--- a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/config/YudaoApiSignatureAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/config/YudaoApiSignatureAutoConfiguration.java
@@ -2,8 +2,11 @@ package cn.iocoder.yudao.framework.signature.config;
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
import cn.iocoder.yudao.framework.signature.core.aop.ApiSignatureAspect;
+import cn.iocoder.yudao.framework.signature.core.fetcher.ApiSignatureSecretFetcher;
+import cn.iocoder.yudao.framework.signature.core.fetcher.DefaultApiSignatureSecretFetcherImpl;
import cn.iocoder.yudao.framework.signature.core.redis.ApiSignatureRedisDAO;
import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate;
@@ -16,8 +19,9 @@ import org.springframework.data.redis.core.StringRedisTemplate;
public class YudaoApiSignatureAutoConfiguration {
@Bean
- public ApiSignatureAspect signatureAspect(ApiSignatureRedisDAO signatureRedisDAO) {
- return new ApiSignatureAspect(signatureRedisDAO);
+ public ApiSignatureAspect signatureAspect(ApiSignatureRedisDAO signatureRedisDAO,
+ ApiSignatureSecretFetcher apiSignatureSecretFetcher) {
+ return new ApiSignatureAspect(signatureRedisDAO, apiSignatureSecretFetcher);
}
@Bean
@@ -25,4 +29,9 @@ public class YudaoApiSignatureAutoConfiguration {
return new ApiSignatureRedisDAO(stringRedisTemplate);
}
-}
+ @Bean
+ @ConditionalOnMissingBean
+ public ApiSignatureSecretFetcher apiSignatureSecretFetcher(ApiSignatureRedisDAO apiSignatureRedisDAO) {
+ return new DefaultApiSignatureSecretFetcherImpl(apiSignatureRedisDAO);
+ }
+}
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java
index e568346aa..3c0bd28d3 100644
--- a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/aop/ApiSignatureAspect.java
@@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.signature.core.annotation.ApiSignature;
+import cn.iocoder.yudao.framework.signature.core.fetcher.ApiSignatureSecretFetcher;
import cn.iocoder.yudao.framework.signature.core.redis.ApiSignatureRedisDAO;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
@@ -36,6 +37,7 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
public class ApiSignatureAspect {
private final ApiSignatureRedisDAO signatureRedisDAO;
+ private final ApiSignatureSecretFetcher apiSignatureSecretFetcher;
@Before("@annotation(signature)")
public void beforePointCut(JoinPoint joinPoint, ApiSignature signature) {
@@ -58,7 +60,7 @@ public class ApiSignatureAspect {
}
// 1.2 校验 appId 是否能获取到对应的 appSecret
String appId = request.getHeader(signature.appId());
- String appSecret = signatureRedisDAO.getAppSecret(appId);
+ String appSecret = apiSignatureSecretFetcher.getAppSecret(appId);
Assert.notNull(appSecret, "[appId({})] 找不到对应的 appSecret", appId);
// 2. 校验签名【重要!】
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/ApiSignatureSecretFetcher.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/ApiSignatureSecretFetcher.java
new file mode 100644
index 000000000..4b20a7adb
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/ApiSignatureSecretFetcher.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.framework.signature.core.fetcher;
+
+/**
+ * Secret 提取器
+ * 允许不同的服务获取 appSecret
+ *
+ * @author diaohang
+ */
+public interface ApiSignatureSecretFetcher {
+
+ /**
+ * 获取 appSecret
+ *
+ * @param appId appId
+ * @return 可以为空,表示找不到对应的 appSecret
+ */
+ String getAppSecret(String appId);
+}
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/DefaultApiSignatureSecretFetcherImpl.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/DefaultApiSignatureSecretFetcherImpl.java
new file mode 100644
index 000000000..7e3157d14
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/signature/core/fetcher/DefaultApiSignatureSecretFetcherImpl.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.framework.signature.core.fetcher;
+
+import cn.iocoder.yudao.framework.signature.core.redis.ApiSignatureRedisDAO;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * @author diaohang
+ */
+@RequiredArgsConstructor
+public class DefaultApiSignatureSecretFetcherImpl implements ApiSignatureSecretFetcher {
+
+ private final ApiSignatureRedisDAO apiSignatureRedisDAO;
+
+ @Override
+ public String getAppSecret(String appId) {
+ return apiSignatureRedisDAO.getAppSecret(appId);
+ }
+}
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java b/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java
index 442374061..98b1b9280 100644
--- a/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/test/java/cn/iocoder/yudao/framework/signature/core/ApiSignatureTest.java
@@ -5,6 +5,7 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.iocoder.yudao.framework.signature.core.annotation.ApiSignature;
import cn.iocoder.yudao.framework.signature.core.aop.ApiSignatureAspect;
+import cn.iocoder.yudao.framework.signature.core.fetcher.ApiSignatureSecretFetcher;
import cn.iocoder.yudao.framework.signature.core.redis.ApiSignatureRedisDAO;
import jakarta.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.Test;
@@ -20,7 +21,8 @@ import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
/**
* {@link ApiSignatureTest} 的单元测试
@@ -31,6 +33,9 @@ public class ApiSignatureTest {
@InjectMocks
private ApiSignatureAspect apiSignatureAspect;
+ @Mock
+ private ApiSignatureSecretFetcher apiSignatureSecretFetcher;
+
@Mock
private ApiSignatureRedisDAO signatureRedisDAO;
@@ -57,12 +62,12 @@ public class ApiSignatureTest {
when(request.getHeader(eq("timestamp"))).thenReturn(String.valueOf(timestamp));
when(request.getHeader(eq("nonce"))).thenReturn(nonce);
when(request.getHeader(eq("sign"))).thenReturn(sign);
- when(request.getParameterMap()).thenReturn(MapUtil.builder()
- .put("v1", new String[]{"k1"}).put("k1", new String[]{"v1"}).build());
+ when(request.getParameterMap()).thenReturn(
+ MapUtil.builder().put("v1", new String[] {"k1"}).put("k1", new String[] {"v1"}).build());
when(request.getContentType()).thenReturn("application/json");
when(request.getReader()).thenReturn(new BufferedReader(new StringReader("test")));
// mock 方法
- when(signatureRedisDAO.getAppSecret(eq(appId))).thenReturn(appSecret);
+ when(apiSignatureSecretFetcher.getAppSecret(eq(appId))).thenReturn(appSecret);
when(signatureRedisDAO.setNonce(eq(appId), eq(nonce), eq(120), eq(TimeUnit.SECONDS))).thenReturn(true);
// 调用