• AOP实现注解式脱敏数据明文查询


    最近又遇到了脱敏数据查询相关的问题,常规的脱敏数据比如用户身份证将中间位数抹去后加入数据库,那么查询时需要手动调用就比较麻烦,不过可以使用自定义注解,利用AOP解析后在切面将数据加密再作为参数注入运行,实现非入侵的脱敏数据明文查询。简单记录一下。

    情境和思路

    用户身份证脱敏,保留前四位和后八位,其余转换为×符号存入数据库。利用aop在方法执行的切面将注解修饰的方法中对应的参数进行加密后注入,就能实现脱敏数据的明文搜索,而不用手动调工具类了。

    实现

    用户

    简单的用户信息,code为身份证。

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
        private int id;
        private String code;
        private String name;
        private byte sex;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Mapper

    简单的搜索接口。

    @Mapper
    public interface UserMapper {
        @Select("select * from user where code = #{code}")
        public User findUserByCode(String code);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    加密工具类

    将加密类型也作为参数,适应不同情况。

    public class EncryptionUtil {
    
        public final static String SELF_CODE = "self_code";
    
        // 加密
        public static String encrypt(String str, String type){
            if (SELF_CODE.equals(type)) {// 身份证前四位加上后六位
                return str.substring(0, 4) + "xxxxxxxx" + str.substring(str.length() - 6);
            }
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    加密注解

    @Encrypt注解,包含两个成员,indexes数组存放需要加密的参数序号,types存放加密类型。

    // 自动加密注解
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Encrypt {
        // 记录需要加密的参数位置
        int[] indexes();
        // 记录加密对像的type
        String[] types();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Aop切面处理类

    关键逻辑类,使用around方法和ProceedingJoinPoint对象将获取对应切面方法的注解和参数信息,对参数进行加密处理后注入。

    @Component
    @Aspect
    public class EncryptAspect {
        @Pointcut("execution(* com.huiluczP.controller.UserController.*(..)) && @annotation(com.huiluczP.annotation.Encrypt)")
    
        private void point() {
    
        }
    
        @Around("point()")
        // 环绕aop,获取切面方法对应的annotation
        private Object around(ProceedingJoinPoint pjp) throws Throwable {
            // 得到方法执行所需的参数
            Object[] args = pjp.getArgs();
            Encrypt encryptParam = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Encrypt.class);
    
            // 获取需要加密的参数位置和加密类型
            int[] indexes = encryptParam.indexes();
            String[] types = encryptParam.types();
    
            // 对参数进行处理
            for(int i=0;i<indexes.length;i++){
                int index = indexes[i];
                args[index] = EncryptionUtil.encrypt((String)args[index], types[i]);
            }
            return pjp.proceed(args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    这边利用execution(* com.huiluczP.controller.UserController.*(..)) && @annotation(com.huiluczP.annotation.Encrypt)将UserController中持有@Encrypt注解的所有方法都归入切面。

    UserController

    传入明文对象进行脱敏数据的查询。在注解中定义了加密参数位置和类型。

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        UserMapper userMapper;
    
        @RequestMapping("/findByCode")
        @ResponseBody
        // 自动加密注解
        @Encrypt(indexes = {0}, types = {EncryptionUtil.SELF_CODE})
        public String findUser(String code){
            User user = userMapper.findUserByCode(code);
            return JSONObject.toJSONString(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    演示

    成功进行了查询。在这里插入图片描述

    总结

    简单的Aop应用,来解决脱敏数据明文查询的代码冗余问题,面向切面确实蛮方便的,就是切面定义表达式比较难写。感兴趣就看看吧。

  • 相关阅读:
    postgresql-窗口函数
    【论文阅读】基于隐蔽带宽的汽车控制网络鲁棒认证(二)
    毕业设计-深度学习的施工安全帽图像检测算法
    2022年陕西省职称申报可以申报什么专业
    自然语言处理状况简介
    分布式架构篇
    深入了解Java 8 新特性:Stream流的实践应用(二)
    IDEA常用快捷键
    企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图
    Java复习总结之正则表达式
  • 原文地址:https://blog.csdn.net/qq_41733192/article/details/126473321