zoukankan      html  css  js  c++  java
  • 自定义@Sensitive对敏感字段进行脱敏处理

    1.通过面向切面基于注解方式进行处理

    @RequestMapping("/test")
        @Sensitive(name={"userName"},phoneNo={"mobile"},email={"email"})
        public Rsp_1 test(){
           //对返回结果进行脱敏处理
        }

    切面类

    /**
     * 切面类,对敏感信息进行脱敏处理
     * @Author mufeng
     * @Date 2019-5-23 16:42
     */
    @Aspect
    @Component
    public class SensitiveAspect {
        private static Logger logger=LoggerFactory.getLogger(SensitiveAspect.class);
       public SensitiveAspect(){
    
       }
       @Pointcut("@annotation(com.mufeng.validator.annotation.Sensitive)")
       public void filter(){
    
       }
    
        /**
         * 对@Sensitive标记的方法进行过滤
         * @param pjp
         * @return
         */
       @Around("filter()")
       public Object afterReturn(ProceedingJoinPoint pjp){
           MethodSignature signature = (MethodSignature)pjp.getSignature();
           Method method = signature.getMethod();
           Object result=null;
           try {
                result = pjp.proceed();
                if(method.isAnnotationPresent(Sensitive.class)){
                    //对返回结果脱敏处理
                    result= SensitiveUtil.sensitiveFilter(method, result);
                }
           } catch (Throwable throwable) {
               logger.error("脱敏异常:"+throwable.getMessage());
           }
           return result;
       }
    }
    
    /**
     * 脱敏工具类
     * @Author mufeng
     * @Date 2019-5-23 17:46
     */
    public class SensitiveUtil {
        private static Logger logger=LoggerFactory.getLogger(SensitiveUtil.class);
        //通过静态map存储,多次访问都是同一资源
        private static Map<String, Map<String, String>> METHOD_MAP = new HashMap();
    
        public SensitiveUtil() {
        }
    
        public static Object sensitiveFilter(Method method, Object result) {
            String methodName = method.getDeclaringClass().getName() + "." + method.getName();
            Map<String, String> map = (Map)METHOD_MAP.get(methodName);
            if (map == null) {
                //注册所有被标记的@Sensitive属性
                map = register(method);
            }
            //脱敏处理
            return desensitiveObject(map, result);
        }
    
        /**
         * 返回结果对象转成JsonObject,进行解析
         * @param filedsMap
         * @param result
         * @return
         */
        private static Object desensitiveObject(Map<String,String> filedsMap, Object result) {
             if(filedsMap.isEmpty()){
                 return result;
             }else{
                 Class<?> clazz = result.getClass();
                 JSONObject jsonObj = (JSONObject)JSONObject.toJSON(result);
                 //解析
                 analysisJson(jsonObj, filedsMap);
                 result = JSONObject.toJavaObject(jsonObj, clazz);
                 return result;
             }
        }
    
        private static void analysisJson(Object jsonObj, Map<String,String> filedsMap) {
            //
            if(jsonObj instanceof JSONArray){
                JSONArray jsonArr = (JSONArray) jsonObj;
                for(int i=0;i<jsonArr.size();i++){
                    Object obj = jsonArr.get(i);
                    //不是JSONObject或JSONArray不进行解析
                    if(!(obj instanceof JSONObject)&&!(obj instanceof JSONArray)){
                        logger.info("JsonArray 不进行解析的第{}属性:{}",i,obj);
                    }else{
                        analysisJson(obj,filedsMap);
                    }
                }
            }else if(jsonObj instanceof JSONObject){
                JSONObject jsonObject = (JSONObject) jsonObj;
                jsonObject.keySet().forEach(key -> {
                    Object obj = jsonObject.get(key);
                    //不是JSONObject或JSONArray,为String进行处理
                    if(!(obj instanceof JSONObject)&&!(obj instanceof JSONArray)){
                        if(obj instanceof String){
                            processDesensitizeJson(jsonObject, key, filedsMap);
                        }else{
                            logger.info("JSONObject不解析属性:{}",obj);
                        }
                    }else{
                        analysisJson(obj,filedsMap);
                    }
                });
            }else{
                logger.info("不是JSONObject和JsonArray不进行解析:{}",jsonObj);
            }
        }
    
        /**
         * 脱敏处理
         * @param jsonObject 返回结果
         * @param key  需脱敏处理字段名
         * @param filedsMap 需脱敏map
         */
        private static void processDesensitizeJson(JSONObject jsonObject, String key, Map<String,String> filedsMap) {
            if(filedsMap.containsKey(key)){
    
                try {
                    logger.info("开始脱敏处理。。。。");
                    //获取脱敏对应handle的方法名
                    String methodName = filedsMap.get(key);
                    //实例化脱敏处理类
                    Class<?> clazz = Class.forName("com.mufeng.validator.util.SensitiveHandle");
                    //通过反射获取脱敏方法
                    Method method = clazz.getMethod(methodName, String.class);
                    //脱敏返回新值
                    String newValue =(String) method.invoke((Object) null, (String) jsonObject.get(key));
                    jsonObject.put(key,newValue);
                } catch (Exception e) {
                    logger.error("脱敏异常:{}",e.getMessage());
                }
            }
        }
    
        private static Map<String, String> register(Method method) {
            Map<String, String> map = new HashMap();
            Sensitive sen = (Sensitive)method.getAnnotation(Sensitive.class);
            if (sen != null) {
                //获取@Sensitive注解所有属性
                Method[] methods = Sensitive.class.getMethods();
                Method[] var4 = methods;
                int var5 = methods.length;
    
                for(int var6 = 0; var6 < var5; ++var6) {
                    Method m = var4[var6];
    
                    try {
                        //获取被标记属性的值
                        String[] keys = (String[])((String[])m.invoke(sen));
                        if (keys == null || keys.length == 0) {
                            break;
                        }
    
                        String[] var9 = keys;
                        int var10 = keys.length;
    
                        for(int var11 = 0; var11 < var10; ++var11) {
                            String s = var9[var11];
                            if (StringUtils.isEmpty(s)) {
                                break;
                            }
                            //属性值作为key,属性名作为value
                            map.put(s, m.getName());
                        }
                    } catch (Exception var13) {
                        logger.error(var13.getMessage());
                    }
                }
    
                METHOD_MAP.put(method.getDeclaringClass().getName() + "." + method.getName(), map);
            }
    
            return map;
        }
    
    /**
     * 处理类
     * @Author mufeng
     * @Date 2019-5-24 10:26
     */
    public class SensitiveHandle {
        public SensitiveHandle() {
        }
    
        public static String name(String name) {
            if (StringUtils.isEmpty(name)) {
                return "";
            } else {
                return name.length() == 1 ? name : SensitiveBean.getMaskCharWay(name, 2, name.length());
            }
        }
    
        public static String idCardNo(String idCardNo) {
            if (StringUtils.isEmpty(idCardNo)) {
                return "";
            } else {
                return idCardNo.length() <= 8 ? idCardNo : SensitiveBean.getMaskCharWay(idCardNo, 5, idCardNo.length() - 4);
            }
        }
    
        public static String driverLicense(String drivingLicense) {
            if (StringUtils.isEmpty(drivingLicense)) {
                return "";
            } else {
                return drivingLicense.length() <= 8 ? drivingLicense : SensitiveBean.getMaskCharWay(drivingLicense, 5, drivingLicense.length() - 4);
            }
        }
    
    }
    
    /**
     * * 进行覆盖 
     * @Author mufeng
     * @Date 2019-5-24 10:33
     */
    public class SensitiveBean {
        private static final String[] cache = new String[]{"*", "**", "***", "****", "*****", "******", "*******", "********", "*********", "**********", "***********", "************", "*************", "**************", "***************", "****************"};
        private static final char coverDefault = '*';
        private String initialCode;
        private int beginIndex;
        private int endIndex;
        private char cover = '*';
    
        public SensitiveBean() {
        }
    
        public SensitiveBean(String initialCode, int beginIndex, int endIndex) {
            this.initialCode = initialCode;
            this.beginIndex = beginIndex;
            this.endIndex = endIndex;
        }
    
        public SensitiveBean(String initialCode, int beginIndex, int endIndex, char cover) {
            this.initialCode = initialCode;
            this.beginIndex = beginIndex;
            this.endIndex = endIndex;
            this.cover = cover;
        }
    
        public static String getMaskSubWay(String initialCode, int beginIndex, int endIndex) {
            SensitiveBean override = new SensitiveBean(initialCode, beginIndex, endIndex);
            return override.getMaskSubWay();
        }
    
        public static String getMaskSubWay(String initialCode, int beginIndex, int endIndex, char cover) {
            SensitiveBean override = new SensitiveBean(initialCode, beginIndex, endIndex, cover);
            return override.getMaskSubWay();
        }
    
        public static String getMaskCharWay(String initialCode, int beginIndex, int endIndex, char cover) {
            SensitiveBean override = new SensitiveBean(initialCode, beginIndex, endIndex, cover);
            return override.getMaskCharWay();
        }
    
        public static String getMaskCharWay(String initialCode, int beginIndex, int endIndex) {
            SensitiveBean override = new SensitiveBean(initialCode, beginIndex, endIndex);
            return override.getMaskCharWay();
        }
    
        public String getMaskSubWay() {
            return null != this.initialCode && !"".equals(this.initialCode) && !"null".equals(this.initialCode) ? this.initialCode.substring(0, this.beginIndex - 1) + cover(this.beginIndex, this.endIndex, this.cover) + this.initialCode.substring(this.endIndex, this.initialCode.length()) : "";
        }
    
        public String getMaskCharWay() {
            if (null != this.initialCode && !"".equals(this.initialCode) && !"null".equals(this.initialCode)) {
                char[] chars = this.initialCode.toCharArray();
                char[] tempBegin = new char[this.beginIndex - 1];
                char[] tempEnd = new char[this.initialCode.length() - this.endIndex];
    
                int varEnd;
                for(varEnd = 0; varEnd < tempBegin.length; ++varEnd) {
                    tempBegin[varEnd] = chars[varEnd];
                }
    
                for(varEnd = 0; varEnd < tempEnd.length; ++varEnd) {
                    tempEnd[varEnd] = chars[this.endIndex + varEnd];
                }
    
                return new String(tempBegin) + cover(this.beginIndex, this.endIndex, this.cover) + new String(tempEnd);
            } else {
                return "";
            }
        }
    
        private static String cover(int beginIndex, int endIndex, char cover) {
            if (beginIndex >= 0 && endIndex >= 0) {
                if (beginIndex > endIndex) {
                    beginIndex ^= endIndex;
                    endIndex ^= beginIndex;
                    beginIndex ^= endIndex;
                }
    
                if (endIndex - beginIndex < cache.length && cover == '*') {
                    return cache[endIndex - beginIndex];
                } else {
                    StringBuilder sb;
                    for(sb = new StringBuilder(endIndex - beginIndex); beginIndex <= endIndex; ++beginIndex) {
                        sb.append(cover);
                    }
    
                    return sb.toString();
                }
            } else {
                return "";
            }
        }
    
        public static String[] getCache() {
            return cache;
        }
    
        public static char getCoverDefault() {
            return '*';
        }
    
        public String getInitialCode() {
            return this.initialCode;
        }
    
        public void setInitialCode(String initialCode) {
            this.initialCode = initialCode;
        }
    
        public int getBeginIndex() {
            return this.beginIndex;
        }
    
        public void setBeginIndex(int beginIndex) {
            this.beginIndex = beginIndex;
        }
    
        public int getEndIndex() {
            return this.endIndex;
        }
    
        public void setEndIndex(int endIndex) {
            this.endIndex = endIndex;
        }
    
        public char getCover() {
            return this.cover;
        }
    
        public void setCover(char cover) {
            this.cover = cover;
        }
  • 相关阅读:
    数据库的规范和SQL优化技巧总结
    新版Intellij idea破解方法(插件IDE Eval Reset)
    容易遗忘的知识点总结
    Java如何搭建脚手架(自动生成通用代码),创建自定义的archetype(项目模板)
    阿里云服务器域名解析和ICP域名备案
    云服务器通过ip无法访问
    FirewallD is not running 远程服务器开启端口报错
    [prerender-spa-plugin] Unable to prerender all routes! 内网打包报错(Navigation Timeout Exceeded)
    vue-cli中的 mode模式、env环境文件,以及其中定义的环境变量
    绘制柱状图和横向条形图,带数据标签!!!
  • 原文地址:https://www.cnblogs.com/mufeng07/p/12673850.html
Copyright © 2011-2022 走看看