美文网首页
SpringBoot中对于字符串进行脱敏操作

SpringBoot中对于字符串进行脱敏操作

作者: LOC_Thomas | 来源:发表于2020-11-04 09:11 被阅读0次

    问题

    在电商业务中,对于一些敏感数据(比如 用户姓名,用户身份证,用户手机号码,用户银行卡等),需要进行脱敏操作,为了业务开发的方便,应该要提供对应的处理方法, 能够使得业务开发能够自由的配置。

    方案

    所以采取了和之前文章中,我们采取的方案是,重新修改默认的ObjectMapper对象,添加一个自定义类型的DesensitizationBeanSerializerModifier,通过对于所有的String字符串都进行过滤,并且提供了 对应的注解 Desensitization,和一些参数, 可以根据不同的脱敏规则进行自由的配置

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    @Documented
    public @interface Desensitization {
    
      //前后分别展示多少个字符
      int showPrefixLength() default 3;
      int showSuffixLength() default 4;
    
      //针对长度进行多种处理,0为不考虑长度
      int strLength() default 0;
    
    }
    

    下面为自己定义的序列化方法

    public static class DesensitizationBeanSerializerModifier extends BeanSerializerModifier {
    
        @Override
        public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
            BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
          for (Object beanProperty : beanProperties) {
            BeanPropertyWriter writer = (BeanPropertyWriter) beanProperty;
            if (isStringType(writer)) {
              Desensitization desensitization = ((BeanPropertyWriter) beanProperty).getAnnotation(Desensitization.class);
              Desensitizations desensitizations = ((BeanPropertyWriter) beanProperty).getAnnotation(Desensitizations.class);
              if (desensitization != null || desensitizations != null) {
                StringDesensitizationJsonSerializer stringDesensitizationJsonSerializer = new StringDesensitizationJsonSerializer();
                if (desensitization != null) {
                  stringDesensitizationJsonSerializer.setDesensitization(desensitization);
                }
                if (desensitizations != null) {
                  stringDesensitizationJsonSerializer.setDesensitizations(desensitizations);
                }
    
                writer.assignSerializer(stringDesensitizationJsonSerializer);
              }
            }
          }
          return beanProperties;
        }
    
        /**
         * 是否是string
         */
        private boolean isStringType(BeanPropertyWriter writer) {
          Class<?> clazz = writer.getType().getRawClass();
          return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz);
        }
    
      }
    

    具体的针对脱敏注解的逻辑操作

    /**
      * 处理字符串脱敏处理
      */
     @NoArgsConstructor
     @AllArgsConstructor
     public static class StringDesensitizationJsonSerializer extends JsonSerializer<Object> {
    
       @Setter
       private Desensitization desensitization;
       @Setter
       private Desensitizations desensitizations;
    
       @Override
       public void serialize(Object o, JsonGenerator jsonGenerator,
           SerializerProvider serializerProvider) throws IOException {
         if (desensitization == null && desensitizations == null) {
           return;
         }
         Desensitization[] desensitizationArray = getDesensitizationArray();
         String value = o.toString();
    
         int valueLength = value.length();
         boolean matchSize = false;
         int zeroLength = -1;
         int index = 0;
         for (Desensitization desensitization : desensitizationArray) {
           if (valueLength == desensitization.strLength()) {
             matchSize = true;
             jsonGenerator
                 .writeString(fixedVal(value, desensitization.showPrefixLength(), desensitization.showSuffixLength()));
           } else if (desensitization.strLength() == 0 && zeroLength == -1) {
             zeroLength = index++;
           } else {
             index++;
           }
         }
    
         if (!matchSize) {
           if(zeroLength != -1) {
             jsonGenerator
                 .writeString(fixedVal(value, desensitizationArray[zeroLength].showPrefixLength(),
                     desensitizationArray[zeroLength].showSuffixLength()));
           } else {
             jsonGenerator
                 .writeString(fixedVal(value, desensitizationArray[0].showPrefixLength(),
                     desensitizationArray[0].showSuffixLength()));
           }
         }
    
       }
    
       private Desensitization[] getDesensitizationArray() {
         int size = 0;
         if (desensitization != null) {
           size++;
         }
    
         if (desensitizations != null) {
           size += desensitizations.value().length;
         }
    
         Desensitization[] desensitizationArray = new Desensitization[size];
         int index = 0;
         if (desensitization != null) {
           desensitizationArray[index++] = desensitization;
         }
    
         if (desensitizations != null) {
           System.arraycopy(desensitizations.value(), 0, desensitizationArray, index, size - index);
         }
         return desensitizationArray;
       }
    
       private String fixedVal(String value, int prefixLength, int suffixLength) {
         if (StringUtils.isBlank(value)) {
           return Strings.repeat("*", value.length());
         }
    
         if(value.length() <= prefixLength + suffixLength) {
           return value;
         }
         int length = value.length();
         String prefix = value.substring(0, prefixLength);
         String suffix = value.substring(length - suffixLength);
         String stars = Strings.repeat("*", length - (prefixLength + suffixLength));
         return prefix + stars + suffix;
       }
     }
    

    这样对于一个Bean里面的对象,都可以进行相关操作。

    下面给一个例子

    
    @Data
    public class DesensitizationsBean {
    
      @Desensitizations(value = {
          @Desensitization(strLength = 4, showPrefixLength = 2, showSuffixLength = 1),
          @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
          @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
          @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
      })
      private String mobileA;
      @Desensitizations(value = {
          @Desensitization,
          @Desensitization(strLength = 1, showPrefixLength = 0, showSuffixLength = 1),
          @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
          @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
          @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
      })
      private String mobileB;
      @Desensitizations(value = {
          @Desensitization,
          @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
          @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
          @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
          @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
      })
      private String mobileC;
      @Desensitizations(value = {
          @Desensitization,
          @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
          @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
          @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
          @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
      })
      private String mobileD;
      @Desensitizations(value = {
          @Desensitization,
          @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
          @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
          @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
          @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
      })
      private String mobileE;
      @Desensitizations(value = {
          @Desensitization,
          @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
          @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
          @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
          @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
      })
      private String mobileF;
      private List<DesensitizationsSubBean> subBeanList;
    
      @Data
      @Builder
      @NoArgsConstructor
      @AllArgsConstructor
      public static class DesensitizationsSubBean {
    
        @Desensitizations(value = {
            @Desensitization,
            @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
            @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
            @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
            @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
        })
        private Long mobile1;
        @Desensitizations(value = {
            @Desensitization,
            @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
            @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
            @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
            @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
        })
        private String mobile2;
        @Desensitizations(value = {
            @Desensitization,
            @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
            @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
            @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
            @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
        })
        private String mobile3;
        @Desensitizations(value = {
            @Desensitization,
            @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
            @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
            @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
            @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
        })
        private String mobile4;
        @Desensitizations(value = {
            @Desensitization,
            @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
            @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
            @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
            @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
        })
        private String mobile5;
        @Desensitizations(value = {
            @Desensitization,
            @Desensitization(strLength = 1, showPrefixLength = 1, showSuffixLength = 1),
            @Desensitization(strLength = 2, showPrefixLength = 1, showSuffixLength = 0),
            @Desensitization(strLength = 3, showPrefixLength = 0, showSuffixLength = 1),
            @Desensitization(strLength = 4, showPrefixLength = 1, showSuffixLength = 1),
        })
        private String mobile6;
      }
    }
    
    
    @GetMapping("/desensitizations")
      public BaseResult desensitizations() {
        DesensitizationsBean desensitizationsBean = new DesensitizationsBean();
        desensitizationsBean.setMobileA("18507313226");
        desensitizationsBean.setMobileB("龙");
        desensitizationsBean.setMobileC("龙哲");
        desensitizationsBean.setMobileD("龙若妍");
        desensitizationsBean.setMobileE("龙若妍好");
        desensitizationsBean.setMobileF("18507313226");
    
        desensitizationsBean.setSubBeanList(
            Lists.newArrayList(
                DesensitizationsSubBean.builder().mobile1(18507313226L).mobile2("龙").mobile3("龙哲").mobile4("龙若妍").mobile5("龙若妍好").mobile6("18507313226").build(),
                DesensitizationsSubBean.builder().mobile1(18507313226L).mobile2("龙").mobile3("龙哲").mobile4("龙若妍").mobile5("龙若妍好").mobile6("18507313226").build(),
                DesensitizationsSubBean.builder().mobile1(18507313226L).mobile2("龙").mobile3("龙哲").mobile4("龙若妍").mobile5("龙若妍好").mobile6("18507313226").build()
            ));
    
        return BaseResult.success(desensitizationsBean);
      }
    

    执行的结果是

    {
      "code": 0,
      "msg": "success",
      "traceId": "6ba0c884b10fbd8f",
      "data": {
        "mobileA": "18********6",
        "mobileB": "龙",
        "mobileC": "龙*",
        "mobileD": "**妍",
        "mobileE": "龙**好",
        "mobileF": "185****3226",
        "subBeanList": [
          {
            "mobile1": 18507313226,
            "mobile2": "龙",
            "mobile3": "龙*",
            "mobile4": "**妍",
            "mobile5": "龙**好",
            "mobile6": "185****3226"
          },
          {
            "mobile1": 18507313226,
            "mobile2": "龙",
            "mobile3": "龙*",
            "mobile4": "**妍",
            "mobile5": "龙**好",
            "mobile6": "185****3226"
          },
          {
            "mobile1": 18507313226,
            "mobile2": "龙",
            "mobile3": "龙*",
            "mobile4": "**妍",
            "mobile5": "龙**好",
            "mobile6": "185****3226"
          }
        ]
      }
    }
    

    这样业务放就只要简单的在想要脱敏的字段上加入对应的注解和配置对应的参数就可以了。

    结束

    转载请注明作者和出处,并添加本页链接。
    原文链接: //tech.cnhnb.com/post/6

    相关文章

      网友评论

          本文标题:SpringBoot中对于字符串进行脱敏操作

          本文链接:https://www.haomeiwen.com/subject/gsbwvktx.html