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); // 调用