mirror of https://gitee.com/xiaonuobase/snowy
添加签名计算
parent
e7f7b1b3ac
commit
ce6b0634f5
|
@ -0,0 +1,113 @@
|
||||||
|
package vip.xiaonuo.common.filter;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
import vip.xiaonuo.common.exception.CommonException;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名过滤器
|
||||||
|
*/
|
||||||
|
public class SignatureInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
|
||||||
|
|
||||||
|
/*从header中读取appSign*/
|
||||||
|
String sign = httpServletRequest.getHeader("appSign");
|
||||||
|
if (StringUtils.isEmpty(sign)) {
|
||||||
|
throw new CommonException("没有签名信息!", 40052050);
|
||||||
|
}
|
||||||
|
|
||||||
|
String appTime = httpServletRequest.getParameter("appTime");
|
||||||
|
if (StringUtils.isEmpty(appTime)) {
|
||||||
|
throw new CommonException("请在Parameter中传入时间戳(毫秒级)!", 40052051);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String[]> bodyData = SignatureInterceptor.sortMapByKey(httpServletRequest.getParameterMap());
|
||||||
|
|
||||||
|
if (bodyData == null) {
|
||||||
|
throw new CommonException("没有请求参数!", 40052052);
|
||||||
|
}
|
||||||
|
|
||||||
|
String original = SignatureInterceptor.transformationUri(bodyData);
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(sign) || !this.isMatching(sign, original)) {
|
||||||
|
throw new CommonException("应用签名验证不通过!", 40024053);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String makeSign(String appId, String appKey, String body) {
|
||||||
|
String sha1 = DigestUtils.sha1Hex(appKey + body + appKey);
|
||||||
|
return DigestUtils.md5Hex(sha1 + appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String[]> sortMapByKey(Map<String, String[]> map) {
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Map<String, String[]> sortMap = new TreeMap<>(Comparator.naturalOrder());
|
||||||
|
sortMap.putAll(map);
|
||||||
|
return sortMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parseBodySign(String sign, Map<String, String[]> body) throws CommonException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isMatching(String sign, String original) {
|
||||||
|
Environment environment = SpringUtil.getBean(Environment.class);
|
||||||
|
String securityAccessKey = environment.getProperty("spring.enjoy-buy.security-access-key");
|
||||||
|
String securityAccessSecret = environment.getProperty("spring.enjoy-buy.security-access-secret");
|
||||||
|
String upSign = this.makeSign(securityAccessKey, securityAccessSecret, original);
|
||||||
|
|
||||||
|
return sign.equalsIgnoreCase(upSign);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String transformationUri(Map<String, String[]> map) {
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
for (String key : map.keySet()) {
|
||||||
|
Object value = map.get(key);
|
||||||
|
if ("appSign".equalsIgnoreCase(key) || value == null || StringUtils.isEmpty(value.toString())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stringBuilder.append(key);
|
||||||
|
stringBuilder.append("=");
|
||||||
|
if (map.get(key).getClass().isArray()) {
|
||||||
|
Object[] objects = (Object[]) map.get(key);
|
||||||
|
StringBuilder valueBuilder = new StringBuilder();
|
||||||
|
for (Object o : objects) {
|
||||||
|
valueBuilder.append(o);
|
||||||
|
valueBuilder.append(",");
|
||||||
|
}
|
||||||
|
valueBuilder.deleteCharAt(valueBuilder.length() - 1);
|
||||||
|
stringBuilder.append(valueBuilder);
|
||||||
|
} else {
|
||||||
|
stringBuilder.append(map.get(key));
|
||||||
|
}
|
||||||
|
stringBuilder.append("&");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stringBuilder.length() > 0) {
|
||||||
|
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
|
import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
|
||||||
import vip.xiaonuo.auth.core.util.StpClientLoginUserUtil;
|
import vip.xiaonuo.auth.core.util.StpClientLoginUserUtil;
|
||||||
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
||||||
|
import vip.xiaonuo.common.filter.SignatureInterceptor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -56,6 +57,10 @@ public class AuthConfigure implements WebMvcConfigurer {
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
// 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关,只是说明哪些接口不需要被拦截器拦截,此处都拦截)
|
// 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关,只是说明哪些接口不需要被拦截器拦截,此处都拦截)
|
||||||
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
|
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
|
||||||
|
registry.addInterceptor(new SignatureInterceptor())
|
||||||
|
.addPathPatterns("/**")
|
||||||
|
/*排除文档相关地址*/
|
||||||
|
.excludePathPatterns("/doc**", "/webjars/**", "/v3/api-docs/**");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Primary
|
@Primary
|
||||||
|
|
|
@ -27,9 +27,9 @@ spring.servlet.multipart.max-file-size=100MB
|
||||||
|
|
||||||
# mysql
|
# mysql
|
||||||
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
|
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/snowy?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useInformationSchema=true
|
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://10.10.10.7:3306/membershipsystem?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useInformationSchema=true
|
||||||
spring.datasource.dynamic.datasource.master.username=root
|
spring.datasource.dynamic.datasource.master.username=MembershipSystem
|
||||||
spring.datasource.dynamic.datasource.master.password=123456
|
spring.datasource.dynamic.datasource.master.password=ZtCMBHbjwanJWxbm
|
||||||
spring.datasource.dynamic.strict=true
|
spring.datasource.dynamic.strict=true
|
||||||
|
|
||||||
# postgres
|
# postgres
|
||||||
|
@ -100,9 +100,9 @@ spring.jackson.serialization.write-dates-as-timestamps=true
|
||||||
# redis configuration
|
# redis configuration
|
||||||
#########################################
|
#########################################
|
||||||
spring.data.redis.database=1
|
spring.data.redis.database=1
|
||||||
spring.data.redis.host=127.0.0.1
|
spring.data.redis.host=10.10.10.3
|
||||||
spring.data.redis.port=6379
|
spring.data.redis.port=6379
|
||||||
spring.data.redis.password=
|
spring.data.redis.password=121121Jie
|
||||||
spring.data.redis.timeout=10s
|
spring.data.redis.timeout=10s
|
||||||
|
|
||||||
spring.data.redis.lettuce.pool.max-active=200
|
spring.data.redis.lettuce.pool.max-active=200
|
||||||
|
@ -201,3 +201,6 @@ springdoc.group-configs[6].packages-to-scan=vip.xiaonuo.sys
|
||||||
# common configuration
|
# common configuration
|
||||||
snowy.config.common.front-url=http://localhost:81
|
snowy.config.common.front-url=http://localhost:81
|
||||||
snowy.config.common.backend-url=http://localhost:82
|
snowy.config.common.backend-url=http://localhost:82
|
||||||
|
|
||||||
|
spring.enjoy-buy.security-access-key=wxd504412d92c5ffe7
|
||||||
|
spring.enjoy-buy.security-access-secret=0c7bf34850bb54158d261e5914e807ee
|
Loading…
Reference in New Issue