美文网首页
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中对于字符串进行脱敏操作

    问题 在电商业务中,对于一些敏感数据(比如 用户姓名,用户身份证,用户手机号码,用户银行卡等),需要进行脱敏操作,...

  • String扫盲贴

    字符串操作是最常见的操作。在Java中,往往使用String类来进行各种字符串操作。而对于String这个类,其实...

  • Java深拷贝

    Java对于对象(包括字符串,这点和Swift不同)默认是浅拷贝,体现在直接赋值操作和集合添加操作中,如果要进行深...

  • iOS字符串操作

    字符串的转换操作 程序开发中,有时需要对字符串中字符大小写进行转换,为此,NSString提供了字符串转换操作的方...

  • Python基础(20) - 字符串支持的基本操作

    字符串常用操作 - 索引 使用[x]进行索引 字符串常用操作 - 分片 使用[start:end]进行分片操作 e...

  • SpringBoot自定义配置以及拦截器配置

    在进行 SpringBoot 项目开发的过程中,对于 SpringBoot 自带的默认配置我们难免有自己不喜欢的地...

  • iOS NSMutableString 初始化方法小记

    在开发过程中,会经常用到 NSMultableString的方法进行字符串的拼接,删除等操作。最近发现如果对于一个...

  • 全方位掌握字符串操作

    在我们项目中,对字符串进行操作那是再频繁不过了,熟练地掌握各种字符串操作,能让我们在各种开发中如鱼得水。 以下操作...

  • 正则表达式

    正则表达式:其实一种规则,有自己特殊的应用,其作用就是针对于字符串进行操作。正则:就是用于操作字符串的规则,其中这...

  • SpringBoot 配置多数据源   MyBatis

    在 SpringBoot 项目中,可能需要使用 MyBatis 对不同数据库进行操作,而SpringBoot默认配...

网友评论

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

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