IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 自定义鉴权注解与AOP -> 正文阅读

[开发测试]自定义鉴权注解与AOP

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

    }
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:22:01  更:2022-03-21 21:23:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:32:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码