数据脱敏
简介
blade-sensitive-spring-boot-starter是一个专门用于处理敏感数据脱敏的Spring Boot启动器。它通过集成Jackson序列化框架,在数据序列化过程中自动对敏感字段进行脱敏处理,确保敏感信息不会在API响应中泄露。
该启动器提供了以下核心功能:
- 基于注解的敏感数据自动脱敏
- 多种预定义脱敏类型(手机号、身份证号、银行卡号等)
项目结构
核心组件
SensitiveModule - 脱敏模块
负责注册脱敏相关的Jackson组件,作为整个脱敏系统的核心入口点。
SensitiveSerializer - 脱敏序列化器
实现了具体的脱敏逻辑,根据不同的脱敏类型对字符串数据进行处理。
SensitiveAnnotationIntrospector - 注解内省器
负责识别带有@Sensitive注解的字段,并为其选择合适的序列化器。
SensitiveJacksonAutoConfiguration - 自动配置类
负责自动装配整个脱敏系统,将各个组件集成到Spring MVC的序列化流程中。
架构概览
详细组件分析
SensitiveModule - 脱敏模块
SensitiveModule继承自Jackson的SimpleModule,主要职责是在模块初始化时注册注解内省器。当Jackson需要序列化对象时,会调用setupModule方法,将SensitiveAnnotationIntrospector添加到注解处理链中。
SensitiveSerializer - 脱敏序列化器
SensitiveSerializer是整个脱敏系统的核心实现,它实现了Jackson的JsonSerializer接口,并通过ContextualSerializer接口支持上下文感知的序列化。
序列化过程包含两个关键步骤:
- 上下文解析:通过createContextual方法从字段注解中提取脱敏参数
- 实际脱敏:根据指定的脱敏类型调用相应的StringMasker方法
SensitiveAnnotationIntrospector - 注解内省器
注解内省器的工作原理非常简单而高效:当Jackson扫描对象字段时,会调用findSerializer方法检查字段是否带有@Sensitive注解。如果有,则直接返回SensitiveSerializer.class,告诉Jackson使用我们自定义的序列化器;如果没有,则继续使用默认的序列化器。
SensitiveJacksonAutoConfiguration - 自动配置
自动配置类负责在整个Spring Boot应用启动时自动装配脱敏系统。它通过@Bean注解创建SensitiveModule实例,并将其注册到Jackson的序列化器链中。
@Sensitive注解使用指南
基本语法
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
annotation class Sensitive(
val type: SensitiveType = SensitiveType.CUSTOMER,
val prefixNoMaskLen: Int = 0,
val suffixNoMaskLen: Int = 0,
val maskStr: String = "*"
)使用示例
1. 基础脱敏类型
data class User(
@Sensitive(type = SensitiveType.MOBILE_PHONE)
val phoneNumber: String,
@Sensitive(type = SensitiveType.ID_CARD)
val idCard: String,
@Sensitive(type = SensitiveType.EMAIL)
val email: String,
@Sensitive(type = SensitiveType.BANK_CARD)
val bankCard: String
)2. 自定义脱敏规则
data class CustomSensitiveData(
// 保留前2位,后3位,中间用#替代
@Sensitive(prefixNoMaskLen = 2, suffixNoMaskLen = 3, maskStr = "#")
val customField: String?,
// 保留用户名首字母,其余用*替代
@Sensitive(type = SensitiveType.CUSTOMER, prefixNoMaskLen = 1, suffixNoMaskLen = 0, maskStr = "*")
val username: String?
)3. 组合使用
data class CompleteUserData(
@Sensitive(type = SensitiveType.CHINESE_NAME)
val name: String?,
@Sensitive(type = SensitiveType.MOBILE_PHONE)
val phone: String?,
@Sensitive(type = SensitiveType.ID_CARD)
val idCard: String?,
@Sensitive(prefixNoMaskLen = 1, suffixNoMaskLen = 1, maskStr = "?")
val secretCode: String?
)脱敏类型详解
预定义脱敏类型
| 类型 | 描述 | 示例输入 | 示例输出 |
|---|---|---|---|
| CHINESE_NAME | 中文姓名 | "张三丰" | "*三丰" |
| ID_CARD | 身份证号 | "340304198907081234" | "340304********1234" |
| FIXED_PHONE | 固定电话 | "01012345678" | "*******5678" |
| MOBILE_PHONE | 手机号码 | "13512345678" | "135****5678" |
| ADDRESS | 地址 | "北京市海淀区上地十街10号" | "北京市海淀区*******" |
| 电子邮箱 | "user@example.com" | "u********@example.com" | |
| BANK_CARD | 银行卡号 | "6222601234567890123" | "622260**********1234" |
| PASSWORD | 密码 | "mypassword123" | "******" |
| KEY | 密钥 | "mysecretkey" | "***key" |
StringMasker工具类实现
StringMasker提供了灵活的脱敏算法,支持精确控制保留的明文部分和掩码字符。
