1.给上游业务方发放key和秘钥才能访问系统 2.上游根据DigestUtils.md5Hex(key.concat(时间戳).concat(秘钥).toUpperCase())生成token 3.传递给下游key,token,timespan 4.下游根据key查找数据库,用key和数据库的秘钥,时间戳重新进行加密 5.下游加密后的结果与上游传的token进行比较
上游传递参数:
@Data
public class AuthenticateBO {
/**
* 请求key
*/
private String appKey;
/**
* 验证加密值 Md5(AppKey+Timespan+SecretKey) 加密的32位大写字符串)
*/
private String token;
/**
* 精确到秒的Unix时间戳
*/
private String timespan;
/**
* 服务code
*/
private String serviceCode;
}
自定义注解:
/**
* 鉴权注解
*
*/
@Target(ElementType.METHOD) // 注解范围,注解使用在方法上
@Retention(RetentionPolicy.RUNTIME) // 生效时间
@Documented
public @interface Authenticate {
/**
* 服务code
*/
String code();
}
AOP切面实现:
/**
* 鉴权切面
*
*/
@Slf4j
@Aspect
@Component
public class AuthenticateAspect extends BaseServiceImpl {
@Pointcut("@annotation(com.xxx.service.paidplatform.annotation.Authenticate)")
public void authenticate() {
}
// 环绕切入,@Around注解可以用来在调用一个具体方法前和调用后来完成一些具体的任务
@Around("authenticate()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
//获取Authenticate注解的服务code
MethodSignature sign = (MethodSignature) joinPoint.getSignature();
Method method = sign.getMethod();
Authenticate authenticate = method.getAnnotation(Authenticate.class);
String code = authenticate.code();
// 参数值数组
Object[] args = joinPoint.getArgs();
AuthenticateBO basePageReqDTO = ObjectHelper.copy(args[0], AuthenticateBO.class);
basePageReqDTO.setServiceCode(code);
authenticate(basePageReqDTO);
return joinPoint.proceed();
}
/**
* 鉴权接口
*
* @since 2020/9/1
*/
protected void authenticate(AuthenticateBO basePageReqDTO) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ApplicationDO applicationDO = null;
ServiceModuleDO serviceModuleDO = null;
try {
String serviceCode = basePageReqDTO.getServiceCode();
Optional.ofNullable(serviceCode)
.orElseThrow(() -> new ServiceException(CustomErrorCodeEnum.SERVICE_CODE_NULLABLE.getValue(), CustomErrorCodeEnum.SERVICE_CODE_NULLABLE.getDescription()));
//获取application_id
Map<String, Object> sqlParams = Maps.newHashMap();
sqlParams.put("isEnable", CommonBooleanEnum.TRUE.getValue());
sqlParams.put("appKey", basePageReqDTO.getAppKey());
applicationDO = dao.queryEntity(ApplicationDO.class, "application.get", sqlParams);
Optional.ofNullable(applicationDO)
.orElseThrow(() -> new ServiceException(CustomErrorCodeEnum.APPLICATION_UN_FIND.getValue(), CustomErrorCodeEnum.APPLICATION_UN_FIND.getDescription()));
//校验appKey和token
String encryptKey = DigestUtils.md5Hex(applicationDO.getAppKey().concat(basePageReqDTO.getTimespan()).concat(applicationDO.getAppSecret()).toUpperCase());
if (!Objects.equals(encryptKey, basePageReqDTO.getToken())) {
throw new ServiceException(CustomErrorCodeEnum.INVALID_APP_KEY.getValue(), CustomErrorCodeEnum.INVALID_APP_KEY.getDescription());
}
//获取订阅的服务
sqlParams.clear();
sqlParams.put("applicationId", applicationDO.getId());
List<ServiceSubscribeDO> serviceSubscribeList = dao.queryEntities(ServiceSubscribeDO.class, "serviceSubscribe.list", sqlParams);
if (CollectionUtils.isEmpty(serviceSubscribeList)) {
throw new ServiceException(CustomErrorCodeEnum.SERVICE_UNSUBSCRIBE.getValue(), CustomErrorCodeEnum.SERVICE_UNSUBSCRIBE.getDescription());
}
List<Long> serviceModuleIds = serviceSubscribeList.stream()
.map(ServiceSubscribeDO::getServiceModuleId)
.collect(Collectors.toList());
//获取服务code
sqlParams.clear();
sqlParams.put("ids", serviceModuleIds);
serviceModuleDO = dao.queryEntities(ServiceModuleDO.class, "serviceModule.list", sqlParams)
.stream().filter(i -> Objects.equals(i.getServiceModuleCode(), serviceCode)).findFirst().orElse(null);
//鉴权
if (Objects.isNull(serviceModuleDO)) {
throw new ServiceException(CustomErrorCodeEnum.SERVICE_UNSUBSCRIBE.getValue(), CustomErrorCodeEnum.SERVICE_UNSUBSCRIBE.getDescription());
}
stopWatch.stop();
createRequestLog(applicationDO.getId(), serviceModuleDO.getServiceId(), basePageReqDTO.getServiceCode(), serviceModuleDO.getId()
, stopWatch.getTotalTimeMillis(), CommonBooleanEnum.TRUE.getValue(), basePageReqDTO.getAppKey());
} catch (Exception e) {
createRequestLog(Objects.isNull(applicationDO) ? 0 : applicationDO.getId()
, Objects.isNull(serviceModuleDO) ? 0 : serviceModuleDO.getServiceId(), basePageReqDTO.getServiceCode()
, Objects.isNull(serviceModuleDO) ? 0 : serviceModuleDO.getId()
, stopWatch.getTotalTimeMillis(), CommonBooleanEnum.FALSE.getValue(), basePageReqDTO.getAppKey());
throw e;
}
}
|