4 changed files with 149 additions and 47 deletions
			
			
		@ -0,0 +1,13 @@ | 
				
			|||||
 | 
					package com.epmet.annotation; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.lang.annotation.*; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * OpenApi验签注解 | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					@Target(ElementType.METHOD) | 
				
			||||
 | 
					@Retention(RetentionPolicy.RUNTIME) | 
				
			||||
 | 
					@Documented | 
				
			||||
 | 
					public @interface OpenApiCheckSign { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,125 @@ | 
				
			|||||
 | 
					package com.epmet.aspect; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import com.epmet.commons.mybatis.aspect.DataFilterAspect; | 
				
			||||
 | 
					import com.epmet.commons.security.sign.openapi.OpenApiSignUtils; | 
				
			||||
 | 
					import com.epmet.commons.tools.exception.EpmetErrorCode; | 
				
			||||
 | 
					import com.epmet.commons.tools.exception.RenException; | 
				
			||||
 | 
					import com.epmet.commons.tools.redis.RedisKeys; | 
				
			||||
 | 
					import com.epmet.commons.tools.redis.RedisUtils; | 
				
			||||
 | 
					import com.epmet.commons.tools.utils.ConvertUtils; | 
				
			||||
 | 
					import com.epmet.commons.tools.utils.Result; | 
				
			||||
 | 
					import com.epmet.feign.EpmetCommonServiceOpenFeignClient; | 
				
			||||
 | 
					import org.apache.commons.lang3.StringUtils; | 
				
			||||
 | 
					import org.aspectj.lang.JoinPoint; | 
				
			||||
 | 
					import org.aspectj.lang.annotation.Aspect; | 
				
			||||
 | 
					import org.aspectj.lang.annotation.Before; | 
				
			||||
 | 
					import org.aspectj.lang.reflect.MethodSignature; | 
				
			||||
 | 
					import org.slf4j.Logger; | 
				
			||||
 | 
					import org.slf4j.LoggerFactory; | 
				
			||||
 | 
					import org.springframework.beans.factory.annotation.Autowired; | 
				
			||||
 | 
					import org.springframework.core.annotation.Order; | 
				
			||||
 | 
					import org.springframework.stereotype.Component; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.RequestBody; | 
				
			||||
 | 
					import org.springframework.web.context.request.RequestAttributes; | 
				
			||||
 | 
					import org.springframework.web.context.request.RequestContextHolder; | 
				
			||||
 | 
					import org.springframework.web.context.request.ServletRequestAttributes; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import javax.servlet.http.HttpServletRequest; | 
				
			||||
 | 
					import java.beans.IntrospectionException; | 
				
			||||
 | 
					import java.lang.reflect.InvocationTargetException; | 
				
			||||
 | 
					import java.lang.reflect.Method; | 
				
			||||
 | 
					import java.lang.reflect.Parameter; | 
				
			||||
 | 
					import java.util.Arrays; | 
				
			||||
 | 
					import java.util.Map; | 
				
			||||
 | 
					import java.util.Set; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@Aspect | 
				
			||||
 | 
					@Component | 
				
			||||
 | 
					@Order(1) | 
				
			||||
 | 
					public class OpenApiCheckSignAspect { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Autowired | 
				
			||||
 | 
					    private RedisUtils redisUtils; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Autowired | 
				
			||||
 | 
					    private EpmetCommonServiceOpenFeignClient commonServiceOpenFeignClient; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private static final Logger log = LoggerFactory.getLogger(DataFilterAspect.class); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * @Description 验签 | 
				
			||||
 | 
					     * @return | 
				
			||||
 | 
					     * @author wxz | 
				
			||||
 | 
					     * @date 2021.03.24 13:39 | 
				
			||||
 | 
					    */ | 
				
			||||
 | 
					    @Before("execution(* com.epmet.controller.*Controller*.*(..)) && @annotation(com.epmet.annotation.OpenApiCheckSign)") | 
				
			||||
 | 
					    public void checkSign(JoinPoint point) { | 
				
			||||
 | 
					        Object[] args = point.getArgs(); | 
				
			||||
 | 
					        MethodSignature methodSignature = (MethodSignature) point.getSignature(); | 
				
			||||
 | 
					        Method method = methodSignature.getMethod(); | 
				
			||||
 | 
					        Parameter[] parameters = method.getParameters(); | 
				
			||||
 | 
					        for (int i = 0; i < parameters.length; i++) { | 
				
			||||
 | 
					            if (parameters[i].isAnnotationPresent(RequestBody.class)) { | 
				
			||||
 | 
					                Map<String, String> argMap = null; | 
				
			||||
 | 
					                try { | 
				
			||||
 | 
					                    argMap = ConvertUtils.entityToMap(args[i]); | 
				
			||||
 | 
					                } catch (Exception e) { | 
				
			||||
 | 
					                    throw new RenException("验签参数转化发生异常"); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (!OpenApiSignUtils.checkSign(argMap, getSecret(getAppId()))) { | 
				
			||||
 | 
					                    // 验签失败
 | 
				
			||||
 | 
					                    throw new RenException(EpmetErrorCode.OPEN_API_SIGN_ERROR.getCode()); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * @return | 
				
			||||
 | 
					     * @Description 取secret | 
				
			||||
 | 
					     * @author wxz | 
				
			||||
 | 
					     * @date 2021.03.24 12:49 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    private String getSecret(String appId) { | 
				
			||||
 | 
					        String secret = (String) redisUtils.get(RedisKeys.getExternalAppSecretKey(appId)); | 
				
			||||
 | 
					        if (StringUtils.isBlank(secret)) { | 
				
			||||
 | 
					            Result<String> result = commonServiceOpenFeignClient.getSecret(appId); | 
				
			||||
 | 
					            if (!result.success()) { | 
				
			||||
 | 
					                throw new RenException("调用common service查询secret失败"); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            secret = result.getData(); | 
				
			||||
 | 
					            if (StringUtils.isBlank(secret)) { | 
				
			||||
 | 
					                throw new RenException(String.format("根据appId%s没有找到对应的secret", appId)); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            redisUtils.set(RedisKeys.getExternalAppSecretKey(appId), secret); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return secret; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * @return | 
				
			||||
 | 
					     * @Description 获取request | 
				
			||||
 | 
					     * @author wxz | 
				
			||||
 | 
					     * @date 2021.03.24 12:52 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    public HttpServletRequest getRequest() { | 
				
			||||
 | 
					        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); | 
				
			||||
 | 
					        ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes; | 
				
			||||
 | 
					        return sra.getRequest(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * @return | 
				
			||||
 | 
					     * @Description 获取appId | 
				
			||||
 | 
					     * @author wxz | 
				
			||||
 | 
					     * @date 2021.03.24 12:53 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    public String getAppId() { | 
				
			||||
 | 
					        HttpServletRequest request = getRequest(); | 
				
			||||
 | 
					        String appId = request.getHeader("AppId"); | 
				
			||||
 | 
					        if (StringUtils.isBlank(appId)) { | 
				
			||||
 | 
					            throw new RenException("请求头中未携带AppId"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return appId; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -1,63 +1,27 @@ | 
				
			|||||
package com.epmet.controller; | 
					package com.epmet.controller; | 
				
			||||
 | 
					
 | 
				
			||||
import com.epmet.commons.security.sign.openapi.OpenApiSignUtils; | 
					import com.epmet.annotation.OpenApiCheckSign; | 
				
			||||
import com.epmet.commons.tools.exception.EpmetErrorCode; | 
					 | 
				
			||||
import com.epmet.commons.tools.exception.RenException; | 
					 | 
				
			||||
import com.epmet.commons.tools.redis.RedisKeys; | 
					 | 
				
			||||
import com.epmet.commons.tools.redis.RedisUtils; | 
					 | 
				
			||||
import com.epmet.commons.tools.utils.ConvertUtils; | 
					 | 
				
			||||
import com.epmet.commons.tools.utils.Result; | 
					import com.epmet.commons.tools.utils.Result; | 
				
			||||
import com.epmet.dto.form.openapi.GetOrgDetailFormDTO; | 
					import com.epmet.dto.form.openapi.GetOrgDetailFormDTO; | 
				
			||||
import com.epmet.feign.EpmetCommonServiceOpenFeignClient; | 
					 | 
				
			||||
import org.apache.commons.lang3.StringUtils; | 
					 | 
				
			||||
import org.springframework.beans.factory.annotation.Autowired; | 
					 | 
				
			||||
import org.springframework.web.bind.annotation.*; | 
					import org.springframework.web.bind.annotation.*; | 
				
			||||
 | 
					
 | 
				
			||||
import java.util.Map; | 
					 | 
				
			||||
 | 
					 | 
				
			||||
@RestController | 
					@RestController | 
				
			||||
@RequestMapping("open-api") | 
					@RequestMapping("open-api") | 
				
			||||
public class OpenApiOrgController { | 
					public class OpenApiOrgController { | 
				
			||||
 | 
					
 | 
				
			||||
    @Autowired | 
					    /** | 
				
			||||
    private EpmetCommonServiceOpenFeignClient commonServiceOpenFeignClient; | 
					     * @Description OpenApiCheckSign是验签注解,OpenApi的接口请加上该注解 | 
				
			||||
 | 
					     * @return | 
				
			||||
    @Autowired | 
					     * @author wxz | 
				
			||||
    private RedisUtils redisUtils; | 
					     * @date 2021.03.24 12:55 | 
				
			||||
 | 
					    */ | 
				
			||||
 | 
					    @OpenApiCheckSign | 
				
			||||
    @PostMapping("/get-org-detail") | 
					    @PostMapping("/get-org-detail") | 
				
			||||
    public Result getOrgDetail(@RequestBody GetOrgDetailFormDTO input, | 
					    public Result getOrgDetail(@RequestBody GetOrgDetailFormDTO input, | 
				
			||||
                               @RequestHeader("appId") String appId) { | 
					                               @RequestHeader("AppId") String appId) { | 
				
			||||
        // 验签
 | 
					 | 
				
			||||
        Map<String, String> params = null; | 
					 | 
				
			||||
        try { | 
					 | 
				
			||||
            params = ConvertUtils.entityToMap(input); | 
					 | 
				
			||||
        } catch (Exception e) { | 
					 | 
				
			||||
            e.printStackTrace(); | 
					 | 
				
			||||
        } | 
					 | 
				
			||||
 | 
					 | 
				
			||||
        if (!OpenApiSignUtils.checkSign(params, getSecret(appId))) { | 
					 | 
				
			||||
            // 验签失败,抛出异常提示
 | 
					 | 
				
			||||
            throw new RenException(EpmetErrorCode.OPEN_API_SIGN_ERROR.getCode()); | 
					 | 
				
			||||
        } | 
					 | 
				
			||||
 | 
					 | 
				
			||||
        return new Result().ok("测试org"); | 
					        return new Result().ok("测试org"); | 
				
			||||
    } | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
    private String getSecret(String appId) { | 
					
 | 
				
			||||
        String secret = (String)redisUtils.get(RedisKeys.getExternalAppSecretKey(appId)); | 
					 | 
				
			||||
        if (StringUtils.isBlank(secret)) { | 
					 | 
				
			||||
            Result<String> result = commonServiceOpenFeignClient.getSecret(appId); | 
					 | 
				
			||||
            if (!result.success()) { | 
					 | 
				
			||||
                throw new RenException("调用common service查询secret失败"); | 
					 | 
				
			||||
            } | 
					 | 
				
			||||
            secret = result.getData(); | 
					 | 
				
			||||
            if (StringUtils.isBlank(secret)) { | 
					 | 
				
			||||
                throw new RenException(String.format("根据appId%s没有找到对应的secret", appId)); | 
					 | 
				
			||||
            } | 
					 | 
				
			||||
            redisUtils.set(RedisKeys.getExternalAppSecretKey(appId), secret); | 
					 | 
				
			||||
        } | 
					 | 
				
			||||
        return secret; | 
					 | 
				
			||||
    } | 
					 | 
				
			||||
 | 
					
 | 
				
			||||
} | 
					} | 
				
			||||
 | 
				
			|||||
					Loading…
					
					
				
		Reference in new issue