refactor(signature): 重构了获取 appSecret 的方式,引入了 ApiSignatureSecretFetcher 接口,允许不同的服务实现获取 appSecret 的逻辑
parent
fd34572c48
commit
4702d8ed74
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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. 校验签名【重要!】
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package cn.iocoder.yudao.framework.signature.core.fetcher;
|
||||
|
||||
/**
|
||||
* Secret 提取器 <br/>
|
||||
* 允许不同的服务获取 appSecret
|
||||
*
|
||||
* @author diaohang
|
||||
*/
|
||||
public interface ApiSignatureSecretFetcher {
|
||||
|
||||
/**
|
||||
* 获取 appSecret
|
||||
*
|
||||
* @param appId appId
|
||||
* @return 可以为空,表示找不到对应的 appSecret
|
||||
*/
|
||||
String getAppSecret(String appId);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.<String, String[]>builder()
|
||||
.put("v1", new String[]{"k1"}).put("k1", new String[]{"v1"}).build());
|
||||
when(request.getParameterMap()).thenReturn(
|
||||
MapUtil.<String, String[]>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);
|
||||
|
||||
// 调用
|
||||
|
|
Loading…
Reference in New Issue