# spring-sensitive **Repository Path**: doobo/spring-sensitive ## Basic Information - **Project Name**: spring-sensitive - **Description**: 基于spring的数据脱敏,实现了"模型类"和"AOP注解"两种方法,可切面改变入参的值 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 28 - **Forks**: 21 - **Created**: 2020-09-04 - **Last Updated**: 2025-06-27 ## Categories & Tags **Categories**: utils **Tags**: None ## README # spring-sensitive [![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) > 基于springboot的数据脱敏,实现了"模型类"和"AOP注解"两种方法,选择其中一种即可 * 选择任意一种即可,若同时使用,先执行controller层的脱敏,再执行模型类里面的脱敏(返回视图默认Jackson) * 基于AOP实现的方法,也可用于其它spring方法上,如无效,记得引入spring的aop包 * 脱敏了的数据,前端传回来后,可进行数据回填,参考下面的"数据回写"部分,基于fastJson实现 ## 如何使用 ``` com.github.doobo spring-sensitive 1.3 ``` ## 使用fastJson脱敏 ``` /** * 基于fastJson的数据脱敏 */ @DesensitizationParams({ @DesensitizationParam(type = SensitiveType.NULL, fields = {"id","address"}), @DesensitizationParam(type = SensitiveType.MOBILE_PHONE, fields = {"phone", "idCard"}), @DesensitizationParam(type = SensitiveType.BANK_CARD, fields = "$..bankCard", mode = HandleType.RGE_EXP), @DesensitizationParam(regExp = "(?<=\\w{2})\\w(?=\\w{1})", fields = "$[0].idCard2", mode = HandleType.RGE_EXP) }) @GetMapping("fast") public List sensitive(){ return Arrays.asList(new UserDesensitization(), new UserDesensitization()); } ``` ## 使用jackson脱敏,基于jackson的JsonSerialize实现 ```java @Data public class UserSensitive { @SensitiveInfo(value = SensitiveType.CHINESE_NAME) String name = "张三"; @SensitiveInfo(value = SensitiveType.ID_CARD) String idCard = "430524202012120832"; @SensitiveInfo(regExp = "(?<=\\w{3})\\w(?=\\w{4})") String idCard2 = "430524202012120832"; @SensitiveInfo(value = SensitiveType.MOBILE_PHONE) String phone = "1234567890"; @SensitiveInfo(value = SensitiveType.FIXED_PHONE) String ext = "0739-8888888"; @SensitiveInfo(value = SensitiveType.ADDRESS) String address = "湖南省长沙市高新区岳麓大道芯城科技园"; @SensitiveInfo(value = SensitiveType.NULL) String address2 = "湖南省"; @SensitiveInfo(value = SensitiveType.BANK_CARD) String bankCard = "622260000027736298837"; @SensitiveInfo(value = SensitiveType.NULL) Integer id = 654321; } ``` ### 方法调用输出 ``` @SpringBootTest public class ApplicationTests { /** * jackson脱敏测试 * @throws JsonProcessingException */ @Test void testSensitive() throws JsonProcessingException { UserSensitive user = new UserSensitive(); ObjectMapper objectMapper = new ObjectMapper(); String str = objectMapper.writeValueAsString(user); System.out.println(str); } } ``` ## 数据回写 有些数据脱敏给前端后,传回给后台时,需要回填到入参里面去,如一些用户ID,手机号等信息 ``` /** * IndexController.java * 数据回填,不给argName默认取第一个参数 * @param pt1 * @param pt2 */ @HyposensitizationParams({ @HyposensitizationParam(type = "card", fields = "bankCard"), @HyposensitizationParam(argName = "a", type = "string"), @HyposensitizationParam(argName = "pt1", type = "phone", fields = {"idCard","phone"}), @HyposensitizationParam(argName = "pt2", type = "reg", fields = {"$..address", "$.bankCard"}, mode = HandleType.RGE_EXP) }) @GetMapping("undo") public String Hyposensitization(UserDesensitization pt1, UserSensitive pt2, String a){ return JSON.toJSONString(Arrays.asList(pt1, pt2, a)); } //PtoUndoObserver.java @Component public class PtoUndoObserver extends UndoObserver { /** * 返回True才执行undoValue */ @Override public boolean matching(UndoVO vo) { return "card".equals(vo.getType()) || "reg".equals(vo.getType()); } /** * 如果是基本类型的入参,并且参数为空,无内存地址,不替换内容 * 继承观察者,可填充到方法的入参里面 */ @Override public void undoValue(UndoVO vo) { if (vo.getType().equals("card")) { vo.undo("...1"); } if (vo.getType().equals("phone")) { vo.undo("......2"); } if (vo.getType().equals("reg")) { vo.undo('.'); } if(vo.getType().equals("string")){ vo.undo("............4"); } if(vo.getType().equals("obj")){ vo.undo(new SingleObj().setAuthor("............5")); } } } ``` ## 自定义脱敏函数 ```java @Service public class SensitiveServiceImpl extends AbstractSensitiveService { @Override public String idCardNum(String idCardNum, int front, int end) { return super.idCardNum(idCardNum, front, end); } @Override public String selfFastJsonHandler(String input, DesensitizationParam param) { if("self".equals(param.tag())){ return "fastJsonSelfHandler:" + input; } return input; } @Override public String selfJacksonHandler(String input, SensitiveInfo param) { return "JacksonHandler:" + input; } } ``` ## 全局配置是否启动相关功能 ```yaml sensitive: enableFastFilter: true enableJackFilter: true enableUndoFilter: true ``` ## 脱敏结果 ![脱敏结果](https://i.loli.net/2020/09/04/W2sUPFdeSBXpm87.png) ## 数据回写结果 ![数据回写](https://i.loli.net/2020/09/10/DOfTpeR917X8YQ4.png)