|
@ -26,6 +26,7 @@ import org.springframework.web.context.request.ServletRequestAttributes; |
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
import java.beans.IntrospectionException; |
|
|
import java.beans.IntrospectionException; |
|
|
|
|
|
import java.lang.reflect.Field; |
|
|
import java.lang.reflect.InvocationTargetException; |
|
|
import java.lang.reflect.InvocationTargetException; |
|
|
import java.lang.reflect.Method; |
|
|
import java.lang.reflect.Method; |
|
|
import java.lang.reflect.Parameter; |
|
|
import java.lang.reflect.Parameter; |
|
@ -33,10 +34,15 @@ import java.util.Arrays; |
|
|
import java.util.Map; |
|
|
import java.util.Map; |
|
|
import java.util.Set; |
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* OpenApi检查请求切面 |
|
|
|
|
|
* 1.验签防止参数篡改 |
|
|
|
|
|
* 2.timestamp+nonce防止请求重放攻击 |
|
|
|
|
|
*/ |
|
|
@Aspect |
|
|
@Aspect |
|
|
@Component |
|
|
@Component |
|
|
@Order(1) |
|
|
@Order(1) |
|
|
public class OpenApiCheckSignAspect { |
|
|
public class OpenApiRequestCheckAspect { |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
private RedisUtils redisUtils; |
|
|
private RedisUtils redisUtils; |
|
@ -53,27 +59,60 @@ public class OpenApiCheckSignAspect { |
|
|
* @date 2021.03.24 13:39 |
|
|
* @date 2021.03.24 13:39 |
|
|
*/ |
|
|
*/ |
|
|
@Before("execution(* com.epmet.controller.*Controller*.*(..)) && @annotation(com.epmet.annotation.OpenApiCheckSign)") |
|
|
@Before("execution(* com.epmet.controller.*Controller*.*(..)) && @annotation(com.epmet.annotation.OpenApiCheckSign)") |
|
|
public void checkSign(JoinPoint point) { |
|
|
public void check(JoinPoint point) { |
|
|
Object[] args = point.getArgs(); |
|
|
Object[] args = point.getArgs(); |
|
|
MethodSignature methodSignature = (MethodSignature) point.getSignature(); |
|
|
MethodSignature methodSignature = (MethodSignature) point.getSignature(); |
|
|
Method method = methodSignature.getMethod(); |
|
|
Method method = methodSignature.getMethod(); |
|
|
Parameter[] parameters = method.getParameters(); |
|
|
Parameter[] parameters = method.getParameters(); |
|
|
|
|
|
|
|
|
|
|
|
HttpServletRequest request = getRequest(); |
|
|
|
|
|
String appId = request.getHeader("AppId"); |
|
|
|
|
|
|
|
|
for (int i = 0; i < parameters.length; i++) { |
|
|
for (int i = 0; i < parameters.length; i++) { |
|
|
if (parameters[i].isAnnotationPresent(RequestBody.class)) { |
|
|
if (parameters[i].isAnnotationPresent(RequestBody.class)) { |
|
|
Map<String, String> argMap = null; |
|
|
Map<String, String> argMap; |
|
|
try { |
|
|
try { |
|
|
argMap = ConvertUtils.entityToMap(args[i]); |
|
|
argMap = ConvertUtils.entityToMap(args[i]); |
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
throw new RenException("验签参数转化发生异常"); |
|
|
throw new RenException("验签参数转化发生异常"); |
|
|
} |
|
|
} |
|
|
if (!OpenApiSignUtils.checkSign(argMap, getSecret(getAppId()))) { |
|
|
|
|
|
|
|
|
argMap.put(""); |
|
|
|
|
|
|
|
|
|
|
|
if (!OpenApiSignUtils.checkSign(argMap, getSecret(appId))) { |
|
|
// 验签失败
|
|
|
// 验签失败
|
|
|
throw new RenException(EpmetErrorCode.OPEN_API_SIGN_ERROR.getCode()); |
|
|
throw new RenException(EpmetErrorCode.OPEN_API_SIGN_ERROR.getCode()); |
|
|
} |
|
|
} |
|
|
|
|
|
checkRepeatRequest(argMap); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 检查请求重放 |
|
|
|
|
|
* @param argMap |
|
|
|
|
|
*/ |
|
|
|
|
|
void checkRepeatRequest(Map<String, String> argMap) { |
|
|
|
|
|
String timestampStr = argMap.get("timestamp"); |
|
|
|
|
|
if (StringUtils.isBlank(timestampStr)) { |
|
|
|
|
|
throw new RenException(EpmetErrorCode.OPEN_API_PARAMS_MISSING.getCode()); |
|
|
|
|
|
} |
|
|
|
|
|
long timestamp = Long.valueOf(timestampStr).longValue(); |
|
|
|
|
|
long now = System.currentTimeMillis(); |
|
|
|
|
|
long requestTimeDiff = 60000; |
|
|
|
|
|
if (Math.abs(now - timestamp) > requestTimeDiff) { |
|
|
|
|
|
// 只允许1分钟之内的请求,允许服务器之间时差为1分钟
|
|
|
|
|
|
throw new RenException(String.format("请求已过时,允许时差为%s ms", requestTimeDiff)); |
|
|
|
|
|
} |
|
|
|
|
|
String nonce = argMap.get("nonce"); |
|
|
|
|
|
String nonceInCache = redisUtils.getString(RedisKeys.getOpenApiNonceKey(nonce)); |
|
|
|
|
|
if (StringUtils.isNotBlank(nonceInCache)) { |
|
|
|
|
|
throw new RenException("请求重复"); |
|
|
|
|
|
} |
|
|
|
|
|
//将nonce缓存到redis,有效期1分钟
|
|
|
|
|
|
redisUtils.set(RedisKeys.getOpenApiNonceKey(nonce), "1", requestTimeDiff); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @return |
|
|
* @return |
|
|
* @Description 取secret |
|
|
* @Description 取secret |
|
@ -114,12 +153,42 @@ public class OpenApiCheckSignAspect { |
|
|
* @author wxz |
|
|
* @author wxz |
|
|
* @date 2021.03.24 12:53 |
|
|
* @date 2021.03.24 12:53 |
|
|
*/ |
|
|
*/ |
|
|
public String getAppId() { |
|
|
//public String getAppId(Parameter[] parameters, Object[] args) {
|
|
|
HttpServletRequest request = getRequest(); |
|
|
// HttpServletRequest request = getRequest();
|
|
|
String appId = request.getHeader("AppId"); |
|
|
// String appId = request.getHeader("AppId");
|
|
|
if (StringUtils.isBlank(appId)) { |
|
|
// if (StringUtils.isBlank(appId)) {
|
|
|
throw new RenException("请求头中未携带AppId"); |
|
|
// for (int i = 0; i < parameters.length; i++) {
|
|
|
} |
|
|
// if (parameters[i].isAnnotationPresent(RequestBody.class)) {
|
|
|
return appId; |
|
|
// Object arg = args[i];
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// appId = getAppIdFromDTO(arg);
|
|
|
|
|
|
// } catch (IllegalAccessException e) {
|
|
|
|
|
|
// e.printStackTrace();
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// if (StringUtils.isBlank(appId)) {
|
|
|
|
|
|
// throw new RenException("未携带AppId");
|
|
|
|
|
|
// }
|
|
|
|
|
|
// return appId;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
//private String getAppIdFromDTO(Object dto) throws IllegalAccessException {
|
|
|
|
|
|
// Field[] declaredFields = dto.getClass().getDeclaredFields();
|
|
|
|
|
|
// for (int i = 0; i < declaredFields.length; i++) {
|
|
|
|
|
|
// Field field = declaredFields[i];
|
|
|
|
|
|
// String fieldName = field.getName();
|
|
|
|
|
|
// if ("appId".equals(fieldName)) {
|
|
|
|
|
|
// field.setAccessible(true);
|
|
|
|
|
|
// String value = (String) field.get(dto);
|
|
|
|
|
|
// return value;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// return null;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) { |
|
|
|
|
|
System.out.println(System.currentTimeMillis()); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |