基于springboot的数据脱敏,实现了"模型类"和"AOP注解"两种方法,选择其中一种即可
- 选择任意一种即可,若同时使用,先执行controller层的脱敏,再执行模型类里面的脱敏(返回视图默认Jackson)
- 基于AOP实现的方法,也可用于其它spring方法上,如无效,记得引入spring的aop包
- 脱敏了的数据,前端传回来后,可进行数据回填,参考下面的"数据回写"部分,基于fastJson实现
<dependency>
<groupId>com.github.doobo</groupId>
<artifactId>spring-sensitive</artifactId>
<version>1.3</version>
</dependency>
/**
* 基于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<UserDesensitization> sensitive(){
return Arrays.asList(new UserDesensitization(), new UserDesensitization());
}
@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"));
}
}
}
@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;
}
}
sensitive:
enableFastFilter: true
enableJackFilter: true
enableUndoFilter: true