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; |
|||
|
|||
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…
Reference in new issue