在 Spring Boot 结合 MyBatis 的项目中,实现字段脱敏(如手机号、身份证号、银行卡号等敏感信息的部分隐藏)可以通过以下方案实现

news/2025/3/22 23:10:10/

在 Spring Boot 结合 MyBatis 的项目中,实现字段脱敏(如手机号、身份证号、银行卡号等敏感信息的部分隐藏)可以通过以下方案实现。以下是分步说明和完整代码示例:


一、实现方案选择

1. 方案一:自定义注解 + Jackson 序列化脱敏
  • 适用场景:数据返回给前端时动态脱敏,数据库存储原始数据。
  • 优点:无侵入性,通过注解灵活控制脱敏字段,与业务逻辑解耦。
  • 核心实现:利用 Jackson 的 JsonSerializer 自定义序列化逻辑。
2. 方案二:MyBatis 类型处理器(TypeHandler)
  • 适用场景:数据库存储时加密或脱敏,查询时解密。
  • 优点:数据存储层直接处理,安全性高。
  • 缺点:需处理加解密逻辑,可能影响查询性能。
3. 方案三:AOP 拦截 Service 层返回结果
  • 适用场景:在业务层统一处理敏感字段。
  • 优点:集中控制脱敏逻辑。
  • 缺点:需遍历对象树,性能开销较大。

二、推荐方案一:Jackson 动态脱敏(完整代码)

1. 定义脱敏策略注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Sensitive {/*** 脱敏策略类型*/SensitiveStrategy strategy();
}
2. 定义脱敏策略枚举
public enum SensitiveStrategy {/*** 手机号脱敏(保留前3后4位)*/PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),/*** 身份证脱敏(保留前1后4位)*/ID_CARD(s -> s.replaceAll("(\\d{1})\\d{13}(\\d{4})", "$1*************$2")),/*** 银行卡脱敏(保留前6后4位)*/BANK_CARD(s -> s.replaceAll("(\\d{6})\\d{9}(\\d{4})", "$1*********$2"));private final Function<String, String> desensitizer;SensitiveStrategy(Function<String, String> desensitizer) {this.desensitizer = desensitizer;}public Function<String, String> getDesensitizer() {return desensitizer;}
}
3. 自定义 Jackson 序列化器
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import java.io.IOException;public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {private SensitiveStrategy strategy;@Overridepublic void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {if (strategy != null && value != null) {// 应用脱敏策略String desensitizedValue = strategy.getDesensitizer().apply(value);gen.writeString(desensitizedValue);} else {gen.writeString(value);}}@Overridepublic JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {Sensitive annotation = property.getAnnotation(Sensitive.class);if (annotation != null && property.getType().getRawClass() == String.class) {SensitiveSerializer serializer = new SensitiveSerializer();serializer.strategy = annotation.strategy();return serializer;}return prov.findNullValueSerializer(property);}
}
4. 在实体类中标记脱敏字段
public class User {private String name;@Sensitive(strategy = SensitiveStrategy.PHONE)private String phone;@Sensitive(strategy = SensitiveStrategy.ID_CARD)private String idCard;// Getters and Setters
}
5. 注册自定义序列化器到 Jackson
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class JacksonConfig {@Beanpublic SimpleModule sensitiveModule() {SimpleModule module = new SimpleModule();module.addSerializer(String.class, new SensitiveSerializer());return module;}
}

三、测试结果

请求返回示例
{"name": "张三","phone": "138****5678","idCard": "3***************1234"
}

四、方案二补充:MyBatis TypeHandler 脱敏(数据库存储加密)

1. 实现 TypeHandler
@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class EncryptTypeHandler implements TypeHandler<String> {private static final String KEY = "your-secret-key-123";@Overridepublic void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {// 存储时加密ps.setString(i, encrypt(parameter));}@Overridepublic String getResult(ResultSet rs, String columnName) throws SQLException {// 查询时解密return decrypt(rs.getString(columnName));}private String encrypt(String data) {// 实现加密逻辑(如 AES)return "encrypted_" + data;}private String decrypt(String data) {// 实现解密逻辑return data.replace("encrypted_", "");}
}
2. 在字段上指定 TypeHandler
public class User {@TableField(typeHandler = EncryptTypeHandler.class)private String bankCard;
}

五、方案选择建议

方案适用场景优点缺点
Jackson 动态脱敏响应数据脱敏无侵入性,灵活配置不适用于非 JSON 输出场景
MyBatis TypeHandler数据库加密存储数据存储安全加解密影响查询性能
AOP 拦截业务层统一处理集中控制逻辑性能开销较大

六、扩展优化

  1. 动态开关脱敏
    通过 @Sensitive 注解增加 enable 属性,结合配置中心动态控制是否脱敏:

    @Sensitive(strategy = SensitiveStrategy.PHONE, enable = "${sensitive.enable:true}")
    
  2. 嵌套对象脱敏
    自定义序列化器支持嵌套对象处理:

    public class User {@Sensitive(strategy = SensitiveStrategy.PHONE)private String phone;@Valid // 支持嵌套对象private Address address;
    }
    
  3. 日志脱敏
    结合 Logback 或 Log4j2 的 Converter 实现日志输出时的脱敏。


通过上述方案,可以灵活、安全地实现敏感字段的脱敏处理,根据实际需求选择合适的实现方式。


http://www.ppmy.cn/news/1581249.html

相关文章

迷你主机与普通台式电脑区别

一、【两者区别】 1、迷你电脑主机大部分都是采用带U的芯片&#xff0c;也就是低功耗芯片&#xff0c;整机功耗在10W-25W左右&#xff1b;普通台式机自然就是用台式机芯片&#xff0c;整机功耗约150W-300W&#xff1b; 2、迷你电脑主机大部分采用低压内存&#xff0c;也就是笔…

MSE分类时梯度消失的问题详解和交叉熵损失的梯度推导

下面是MSE不适合分类任务的解释&#xff0c;包含梯度推导。以及交叉熵的梯度推导。 前文请移步笔者的另一篇博客&#xff1a;大模型训练为什么选择交叉熵损失&#xff08;Cross-Entropy Loss&#xff09;&#xff1a;均方误差&#xff08;MSE&#xff09;和交叉熵损失的深入对比…

简述一下Unity中的碰撞检测

碰撞检测的基本工作原理 Unity中的碰撞检测是游戏开发中的核心功能&#xff0c;依赖于NVIDIA的PhysX物理引擎实现。它通过碰撞体&#xff08;Collider&#xff09;和刚体&#xff08;Rigidbody&#xff09;两个主要组件来检测和响应游戏对象之间的物理交互&#xff0c;遵循以下…

如何用Deepseek制作流程图?

使用Deepseek制作流程图&#xff0c;本质上是让AI根据你的需求&#xff0c;生成相关流程图的代码&#xff0c;然后在流程图编辑器中渲染&#xff0c;类似于Python一样&#xff0c;ChatGPT可以生成代码&#xff0c;但仍需在IDE中执行。 你知道绘制流程图最高效的工具是什么吗&a…

webpack等构建工具如何支持移除未使用的代码

Webpack 等构建工具通过 Tree Shaking&#xff08;摇树优化&#xff09;和 Dead Code Elimination&#xff08;无用代码消除&#xff09;技术来移除未使用的代码。以下是具体实现原理、配置方法及最佳实践&#xff1a; 一、Tree Shaking 的原理 Tree Shaking 是一种基于 ES Mo…

PHP、Java、Go、Python、Node.js、Ruby 写的接口,服务器承载量对比

以下是PHP、Java、Go、Python、Node.js和Ruby在接口服务器承载量方面的对比分析&#xff0c;基于其I/O模型、并发处理机制和实际性能测试结果&#xff1a; 1. PHP I/O模型&#xff1a;采用阻塞式I/O&#xff0c;每个请求对应一个独立进程&#xff08;如Apache的Prefork模式&…

用 pytorch 从零开始创建大语言模型(一):理解大型语言模型

用 pytorch 从零开始创建大语言模型&#xff08;一&#xff09;&#xff1a;理解大型语言模型 1 理解大型语言模型LLM的语言理解能力LLM的进步来自深度学习LLM 与 早期 NLP 模型的不同LLM 成功的关键本系列的目标 1.1 什么是 LLM&#xff1f;LLM 中的 "Large"&#…

学习记录-Ajax-图书列表渲染

目录 图书列表渲染功能描述图书列表渲染实现步骤1.准备工作2.数据渲染3.数据添加4.数据删除5.数据编辑 完整实例代码 图书列表渲染功能描述 页面刷新时&#xff0c;列表自动渲染图书列表数据已渲染的图书列表数据可以进行编辑和删除功能点击添加按钮&#xff0c;可以添加图书信…