Browse Source

新增:

验签注解和AOP
dev_shibei_match
wxz 4 years ago
parent
commit
0e0f3142e4
  1. 2
      epmet-gateway/src/main/java/com/epmet/auth/ExtAppFetchTokenAuthProcessor.java
  2. 13
      epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/annotation/OpenApiCheckSign.java
  3. 125
      epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/aspect/OpenApiCheckSignAspect.java
  4. 56
      epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/controller/OpenApiOrgController.java

2
epmet-gateway/src/main/java/com/epmet/auth/ExtAppFetchTokenAuthProcessor.java

@ -57,7 +57,7 @@ public class ExtAppFetchTokenAuthProcessor extends ExtAppAuthProcessor {
if (!StringUtils.isBlank(appId)) {
ServerHttpRequest.Builder mutate = exchange.getRequest().mutate();
mutate.header("appId", appId);
mutate.header("AppId", appId);
exchange.mutate().request(mutate.build()).build();
}
}

13
epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/annotation/OpenApiCheckSign.java

@ -0,0 +1,13 @@
package com.epmet.annotation;
import java.lang.annotation.*;
/**
* OpenApi验签注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OpenApiCheckSign {
}

125
epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/aspect/OpenApiCheckSignAspect.java

@ -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;
}
}

56
epmet-module/epmet-ext/epmet-ext-server/src/main/java/com/epmet/controller/OpenApiOrgController.java

@ -1,63 +1,27 @@
package com.epmet.controller;
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.annotation.OpenApiCheckSign;
import com.epmet.commons.tools.utils.Result;
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 java.util.Map;
@RestController
@RequestMapping("open-api")
public class OpenApiOrgController {
@Autowired
private EpmetCommonServiceOpenFeignClient commonServiceOpenFeignClient;
@Autowired
private RedisUtils redisUtils;
/**
* @Description OpenApiCheckSign是验签注解OpenApi的接口请加上该注解
* @return
* @author wxz
* @date 2021.03.24 12:55
*/
@OpenApiCheckSign
@PostMapping("/get-org-detail")
public Result getOrgDetail(@RequestBody GetOrgDetailFormDTO input,
@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());
}
@RequestHeader("AppId") String appId) {
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…
Cancel
Save