| 
						
						
							
								
							
						
						
					 | 
					@ -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,25 +59,58 @@ 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); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    /** | 
					 | 
					 | 
					    /** | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -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()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} |