数据脱敏

基于SpringBoot 实现数据脱敏

0、本文参考的链接

1、jackson
2、数据脱敏

1、实现方法

1、最简单的的,项目中引入Hutool工具包,调用其中的方法即可。【个人觉得不太好】
2、本文采用jackson去实现,jackson的简单学习 可以参考jackson

2、项目依赖:SpringBoot-Web 、Apache.common、lombok

PS: Spring默认的序列化框架就是 jackson,所以不需要单独引入

点击查看代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.12.0</version>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>

3、定义脱敏枚举类

点击查看代码
/**
 * 数据脱敏类型
 */
public enum SensitiveEnum {

    /**
     * 身份证号码
     */
    ID_CARD,
    /**
     * 电子邮件
     */
    EMAIL,

    /**
     * 手机号码
     */
    MOBILE_PHONE;

}

4、不同类型字段脱敏处理

点击查看代码
public class SensitiveUtils {

    /**
     * 身份证脱敏
     *
     * @param idcard
     * @return
     */
    public static String isCardNumber(String idcard) {
        if (StringUtils.isBlank(idcard)) {
            return "";
        }
        return StringUtils.left(idcard, 3).concat(StringUtils
                .removeStart(StringUtils.leftPad(StringUtils.right(idcard, 4), StringUtils.length(idcard), "*"),
                        "***"));

    }

    /**
     * 电子邮箱脱敏
     *
     * @param email
     * @return
     */
    public static String email(String email) {
        if (StringUtils.isBlank(email)) {
            return "";
        }

        if (StringUtils.indexOf(email, "@") <= 1) {
            return "";
        }
        return StringUtils.leftPad(
                StringUtils.right(email, StringUtils.length(email) - StringUtils.indexOf(email, "@")),
                StringUtils.length(email),
                "*");

    }


    /**
     * 手机号码
     *
     * @param phone
     * @return
     */
    public static String mobilePhone(String phone) {
        if (StringUtils.isBlank(phone)) {
            return "";
        }

        return StringUtils.left(phone, 3).concat(StringUtils
                .removeStart(StringUtils.leftPad(StringUtils.right(phone, 4), StringUtils.length(phone), "*"),
                        "***"));
    }

}

5、实现序列化类

点击查看代码
public class SensitiveSerialize extends JsonSerializer<String> implements ContextualSerializer {

    SensitiveEnum enumtype;


    public SensitiveSerialize() {

    }

    public SensitiveSerialize(SensitiveEnum type) {
        this.enumtype = type;
    }

    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        switch (this.enumtype) {
            case ID_CARD:
                jsonGenerator.writeString(SensitiveUtils.isCardNumber(s));
                break;
            case EMAIL:
                jsonGenerator.writeString(SensitiveUtils.email(s));
                break;
            case MOBILE_PHONE:
                jsonGenerator.writeString(SensitiveUtils.mobilePhone(s));
                break;
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (!Objects.isNull(beanProperty)) {
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                SensitiveAnnantion sensitiveAnnantion = beanProperty.getAnnotation(SensitiveAnnantion.class);
                if (Objects.isNull(sensitiveAnnantion)) {
                    sensitiveAnnantion = beanProperty.getContextAnnotation(SensitiveAnnantion.class);
                } else {
                    return new SensitiveSerialize(sensitiveAnnantion.value());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }

        return serializerProvider.findNullValueSerializer(beanProperty);
    }

}

6、定义注解

点击查看代码
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveSerialize.class)
public @interface SensitiveAnnantion {
    SensitiveEnum value();
}

7、测试

点击查看代码
## 实体类
@Data
@AllArgsConstructor
@Builder
public class UserModel {

    private Long userid;

    private String username;

    @SensitiveAnnantion(value = SensitiveEnum.EMAIL)
    private String email;

    @SensitiveAnnantion(value = SensitiveEnum.MOBILE_PHONE)
    private String phone;

    @SensitiveAnnantion(value = SensitiveEnum.ID_CARD)
    private String idcard;
}

## controller
@RestController
public class DemoController {

    @GetMapping(value = "/query")
    public UserModel Query() {
        return UserModel.builder()
                .email("2575102291@qq.com")
                .phone("17609329556")
                .idcard("111111111111111111")
                .userid(2023L)
                .username("张三")
                .build();
    }
}

## 测试结果
{
  "userid": 2023,
  "email": "**********@qq.com",
  "username": "张三",
  "phone": "176****9556",
  "idcard": "111***********1111"
}
Response file saved.
> 2023-03-19T121644.200.json

8、代码地址

https://gitee.com/douguangji/SpringBoot-Gather.git
image

posted @ 2023-03-19 12:46  一个努力的人QAQ  阅读(112)  评论(0编辑  收藏  举报