使用切面对出参脱敏

一共两种用法 

(1) 在实体类使用

 (2)在有返回值的方法上使用

package com.hmdp.aop.annotation;

import com.hmdp.constant.SensitiveType;

import java.lang.annotation.*;

/**
 * @Author: ldj
 * @Date: 2024/03/28/10:22
 * @Description: 敏感字段注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
@Documented
public @interface Desensitized {

    /**
     * 脱敏数据类型
     */
    SensitiveType type() default SensitiveType.CUSTOMER;

    /**
     * 方法返回值字段脱敏 配置规则 字段名_左不覆盖索引_右不覆盖索引,如password_0_0
     */
    String[] rules() default {};
}
package com.hmdp.aop.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hmdp.aop.annotation.Desensitized;
import com.hmdp.utils.DesensitizedUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @Author: ldj
 * @Date: 2024/03/28/14:15
 * @Description: 去敏切面
 */
@Aspect
@Component
public class DesensitizedAspect {

    @Around("@annotation(com.hmdp.aop.annotation.Desensitized)")
    public Object desensitize(ProceedingJoinPoint joinPoint) throws Throwable {
        //前置处理
        Object[] args = joinPoint.getArgs();
        System.out.println(Arrays.toString(args));

        //执行目标方法
        Object obj = joinPoint.proceed();

        //后置处理
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Desensitized annotation = AnnotationUtils.getAnnotation(signature.getMethod(), Desensitized.class);
        assert annotation != null;
        String[] rules = annotation.rules();
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(obj));
        for (String rule : rules) {
            //password_0_0
            String[] split = rule.split("_");
            String fieldName = split[0];
            String value = (String) jsonObject.get(fieldName);
            //去敏
            value = DesensitizedUtil.cover(value, Integer.parseInt(split[1]), Integer.parseInt(split[2]), "*");
            jsonObject.put(fieldName, value);

        }

        return jsonObject.toJavaObject(obj.getClass());
    }

}
package com.hmdp.utils;

import com.hmdp.aop.annotation.Desensitized;
import com.hmdp.constant.SensitiveType;
import com.hmdp.entity.User;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.hmdp.constant.SensitiveType.*;

/**
 * @Author: ldj
 * @Date: 2024/03/28/9:26
 * @Description: 脱敏工具类
 */
public class DesensitizedUtil<T> {

    //单个对象
    public static <T> T desensitize(T t) throws IllegalAccessException {
        List<Field> sensitiveFields = getSensitiveField(t.getClass());
        for (Field sensitiveField : sensitiveFields) {
            Desensitized annotation = sensitiveField.getAnnotation(Desensitized.class);
            SensitiveType sensitiveType = annotation.type();
            sensitiveField.setAccessible(true);
            String value = (String) sensitiveField.get(t);
            String maskValue = convertByType(value, sensitiveType);
            sensitiveField.set(t, maskValue);
        }

        return t;
    }

    //多个对象
    public static <T> List<T> desensitizes(List<T> ts) throws IllegalAccessException {
        List<T> list = new ArrayList<>();
        for (T t : ts) {
            list.add(desensitize(t));
        }
        return list;
    }

    private static <T> List<Field> getSensitiveField(Class<T> clazz) {
        List<Field> tempList = new ArrayList<>();
        tempList.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempList.addAll(Arrays.asList(clazz.getDeclaredFields()));

        List<Field> fields = new ArrayList<>();
        for (Field field : tempList) {
            if (field.isAnnotationPresent(Desensitized.class)) {
                fields.add(field);
            }
        }

        return fields;
    }

    private static String convertByType(String value, SensitiveType sensitiveType) {
        switch (sensitiveType) {
            case CUSTOMER:
                value = cover(value, CUSTOMER.getPrefixNoMaskLen(), CUSTOMER.getSuffixNoMaskLen(), "*");
                break;
            case CHINESE_NAME:
                value = cover(value, CHINESE_NAME.getPrefixNoMaskLen(), CHINESE_NAME.getSuffixNoMaskLen(), "*");
                break;
            case ID_CARD_NUM:
                value = cover(value, ID_CARD_NUM.getPrefixNoMaskLen(), ID_CARD_NUM.getSuffixNoMaskLen(), "*");
                break;
            case MOBILE_PHONE:
                value = cover(value, MOBILE_PHONE.getPrefixNoMaskLen(), ID_CARD_NUM.getSuffixNoMaskLen(), "*");
                break;
            case FIXED_PHONE:
                value = cover(value, FIXED_PHONE.getPrefixNoMaskLen(), FIXED_PHONE.getSuffixNoMaskLen(), "*");
                break;
            case PASSWORD:
                value = cover(value, PASSWORD.getPrefixNoMaskLen(), PASSWORD.getSuffixNoMaskLen(), "*");
                break;
            case BANKCARD:
                value = cover(value, BANKCARD.getPrefixNoMaskLen(), BANKCARD.getSuffixNoMaskLen(), "*");
                break;
            case EMAIL:
                value = cover(value, EMAIL.getPrefixNoMaskLen(), EMAIL.getSuffixNoMaskLen(), "*");
                break;
            case ADDRESS:
                value = cover(value, ADDRESS.getPrefixNoMaskLen(), ADDRESS.getSuffixNoMaskLen(), "*");
                break;
        }

        return value;
    }

//    public static String cover2(String origin, int prefixNoMaskLen, int suffixNoMaskLen, String maskStr) {
//        if (origin == null) {
//            return null;
//        }
//
//        StringBuilder sb = new StringBuilder();
//        for (int i = 0, n = origin.length(); i < n; i++) {
//            if (i < prefixNoMaskLen) {
//                sb.append(origin.charAt(i));
//                continue;
//            }
//            if (i > (n - suffixNoMaskLen - 1)) {
//                sb.append(origin.charAt(i));
//                continue;
//            }
//            sb.append(maskStr);
//        }
//        return sb.toString();
//    }

    public static String cover(String s, int prefixNoMaskLen, int suffixNoMaskLen, String symbol) {
        if (StringUtils.isBlank(s)) {
            return "";
        }

        if (StringUtils.isBlank(symbol)) {
            symbol = "*";
        }

        int length = s.length();
        if (length > prefixNoMaskLen + suffixNoMaskLen) {
            String prefix = StringUtils.left(s, prefixNoMaskLen);
            String suffix = StringUtils.right(s, suffixNoMaskLen);
            s = StringUtils.rightPad(prefix, StringUtils.length(s) - suffixNoMaskLen, symbol).concat(suffix);
        }

        return s;
    }

    public static void main(String[] args) throws IllegalAccessException {
        User user1 = new User().setPhone("13588833061").setPassword("wdergr4594fe!");
        User user2 = new User().setPhone("13599933061").setPassword("wdergr5464fe!");
        User user = DesensitizedUtil.desensitize(user1);
        System.out.println(user1.toString());

        List<User> desensitizes = DesensitizedUtil.desensitizes(Arrays.asList(user1, user2));
        System.out.println(desensitizes);
    }

}

package com.hmdp.constant;

/**
 * @Author: ldj
 * @Date: 2024/03/28/9:50
 * @Description: 字段敏感类型
 */
public enum SensitiveType {

    /**
     * 自定义
     */
    CUSTOMER(0,0),
    /**
     * 名称
     **/
    CHINESE_NAME(1,0),
    /**
     * 身份证证件号
     **/
    ID_CARD_NUM(0,4),
    /**
     * 手机号
     **/
    MOBILE_PHONE(3,4),
    /**
     * 固定电话
     */
    FIXED_PHONE(0,4),
    /**
     * 密码
     **/
    PASSWORD(0,0),
    /**
     * 银行卡号
     */
    BANKCARD(6,4),
    /**
     * 邮箱
     */
    EMAIL(1,4),
    /**
     * 地址
     */
    ADDRESS(9,0);

    private int prefixNoMaskLen;
    private int suffixNoMaskLen;

    SensitiveType(int prefixNoMaskLen,int suffixNoMaskLen){
        this.prefixNoMaskLen = prefixNoMaskLen;
        this.suffixNoMaskLen = suffixNoMaskLen;
    }

    public int getPrefixNoMaskLen() {
        return prefixNoMaskLen;
    }

    public void setPrefixNoMaskLen(int prefixNoMaskLen) {
        this.prefixNoMaskLen = prefixNoMaskLen;
    }

    public int getSuffixNoMaskLen() {
        return suffixNoMaskLen;
    }

    public void setSuffixNoMaskLen(int suffixNoMaskLen) {
        this.suffixNoMaskLen = suffixNoMaskLen;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值