基于Jackson实现API接口数据脱敏

news/2024/11/8 0:02:41/

一、背景

用户的一些敏感数据,例如手机号、邮箱、身份证等信息,在数据库以明文存储(加密存储见《基于Mybatis-Plus拦截器实现MySQL数据加解密》), 但在接口返回数据给浏览器(或三方客户端)时,希望对这些敏感数据进行脱敏。 同时在浏览器提交数据更新到后端接口时,后端接口需要判断敏感数据是否已脱敏,如果已脱敏则需要直接丢弃。

 

二、Jackson介绍

Jackson是SpringBoot默认的Json序列化和反序列化库,点击这里查看Jackson注解官方文档.

本文通过使用Jackson的@JsonSerialize注解实现序列化时脱敏操作,通过使用Jackson的@JsonDeserialize注解实现反序列化时脱敏数据检测并丢弃操作。

三、使用方法

该脱敏拦截器功能在wutong-base-api包(公司内部包)已经实现,如果您的项目已经依赖了base-api,就可以直接使用。

另外,在码云上有Demo案例,见: spring-jackson

基于wutong-base-api包的使用步骤如下。

1、添加wutong-base-api依赖

<dependency><groupId>com.talkweb</groupId><artifactId>wutong-base-api</artifactId><version>请使用最新版本</version>
</dependency>

2、在yaml配置开关,启用加解密

spring:jackson:sensitive:# 序列化时是否对手机号进行脱敏,反序列化时是否过滤脱敏数据mobile: true# 序列化时是否对邮箱进行脱敏,反序列化时是否过滤脱敏数据email: true# 序列化时是否对身份证号进行脱敏,反序列化时是否过滤脱敏数据identity: true

3、定义VO类,使用Jackson注解实现数据脱敏

API接口出参(Rsp),敏感数据序列化时脱敏

public class UserRspVO {private Long id;private String name;@JsonSerialize(using = CustomerJackSon.MobileSerialize.class)private String mobile;@JsonSerialize(using = CustomerJackSon.EmailSerialize.class)private String email;@JsonSerialize(using = CustomerJackSon.IdentitySerialize.class)private String identity;
}

API接口入参(Req),过滤已脱敏的数据,直接丢弃

public class UserReqVO {private Long id;private String name;@JsonDeserialize(using = CustomerJackSon.MobileDeSerialize.class)private String mobile;@JsonDeserialize(using = CustomerJackSon.EmailDeSerialize.class)private String email;@JsonDeserialize(using = CustomerJackSon.IdentityDeSerialize.class)private String identity;
}

定义Controller接口

@RestController
@RequestMapping("/user")
public class UserController {@GetMappingpublic UserRspVO get() {UserRspVO rsp = new UserRspVO();rsp.setId(1L);rsp.setName("张三");rsp.setMobile("18866661234");rsp.setEmail("zhangsan@qq.com");rsp.setIdentity("434113199901015566");return rsp;}@PutMappingpublic UserRspVO put(@RequestBody UserReqVO req) {System.out.println(req);UserRspVO rsp = new UserRspVO();BeanUtils.copyProperties(req, rsp);return rsp;}
}

接口请求示例:

GET http://localhost:8080/user入参:
无出参:
{"id": "1","name": "张三","mobile": "188****1234", // 配置了mobile=true"email": "zhangsan@qq.com", // 配置了email=false"identity": "434113199901015566" // 未配置identity,默认为false
}
PUT http://127.0.0.1:8080/user入参:
{"id": "12124","name": "张三","mobile": "188****1234","email": "zh****@qq.com","identity": "434***********5566"
}Controller反序列化后接收到的数据:
{"id": "12124","name": "张三","mobile": null, // 配置了mobile=true"email": "zh****@qq.com", // 配置了email=false"identity": "434***********5566" // 未配置identity,默认为false
}

四、实现原理

1、SpringBoot定义变量实现脱敏开关

读取yaml配置

@ConfigurationProperties(prefix = "spring.jackson.sensitive")
public class JacksonProperties {private Boolean mobile;private Boolean email;private Boolean identity;
}

变量注入到JacksonConfig

@Configuration
@EnableConfigurationProperties(JacksonProperties.class)
public class JacksonConfig {@Beanpublic ObjectMapper objectMapper(JacksonProperties props) {ObjectMapper mapper = new ObjectMapper();ContextAttributes attrs = ContextAttributes.getEmpty().withSharedAttribute("mobile", props.getMobile()).withSharedAttribute("email", props.getEmail()).withSharedAttribute("identity", props.getIdentity());mapper.setDefaultAttributes(attrs);return mapper;}
}

2、实现序列化、反序列化逻辑

public class CustomerJackSon {/*** 手机号脱敏序列化*/public static class MobileSerialize extends JsonSerializer<String> {@Overridepublic void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {if (null == value || value.length() != 11) {jsonGenerator.writeString(value);return;}Boolean mobile = (Boolean) serializerProvider.getAttribute("mobile");if (null == mobile || !mobile) {jsonGenerator.writeString(value);return;}jsonGenerator.writeString(value.substring(0, 3) + "****" + value.substring(7));}}/*** 手机号脱敏数据检测并丢弃*/public static class MobileDeSerialize extends JsonDeserializer<String> {@Overridepublic String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {String value = p.getText();if (null == value || value.length() != 11) {return value;}Boolean mobile = (Boolean) ctxt.getAttribute("mobile");if (null == mobile || !mobile) {return value;}if (value.contains("*")) {return null;}return value;}}/*** 邮箱脱敏序列化*/public static class EmailSerialize extends JsonSerializer<String> {@Overridepublic void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {if (null == value || value.length() < 5) {jsonGenerator.writeString(value);return;}String[] split = value.split("@");if (split.length != 2 || split[0].length() < 2 || split[1].length() < 2) {jsonGenerator.writeString(value);return;}Boolean email = (Boolean) serializerProvider.getAttribute("email");if (null == email || !email) {jsonGenerator.writeString(value);return;}jsonGenerator.writeString(split[0].substring(0, 2) + "****@" + split[1]);}}/*** 邮箱脱敏数据检测并丢弃*/public static class EmailDeSerialize extends JsonDeserializer<String> {@Overridepublic String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {String value = p.getText();if (null == value || value.length() < 5) {return value;}Boolean email = (Boolean) ctxt.getAttribute("email");if (null == email || !email) {return value;}if (value.contains("*")) {return null;}return value;}}/*** 身份证脱敏序列化*/public static class IdentitySerialize extends JsonSerializer<String> {@Overridepublic void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {if (null == value || value.length() != 18) {jsonGenerator.writeString(value);return;}Boolean identity = (Boolean) serializerProvider.getAttribute("identity");if (null == identity || !identity) {jsonGenerator.writeString(value);return;}jsonGenerator.writeString(value.substring(0, 3) + "***********" + value.substring(14));}}/*** 身份证脱敏数据检测并丢弃*/public static class IdentityDeSerialize extends JsonDeserializer<String> {@Overridepublic String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {String value = p.getText();if (null == value || value.length() != 18) {return value;}Boolean identity = (Boolean) ctxt.getAttribute("identity");if (null == identity || !identity) {return value;}if (value.contains("*")) {return null;}return value;}}
}

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

相关文章

ORA-39001

oracle 11g执行expdp导出脚本时报错&#xff1a; ORA-39001:参数值无效 ORA-39000:转储文件说明错误 ORA-31641:无法创建转储文件“xxxxx.dmp" ORA-27038:所创建的文件已存在 OSD-04010&#xff1a;?????<create>??,?????????? 解决方式&#xf…

ORA-39002 ORA-39168

impdp导入报错ORA-39002 ORA-39168 $ impdp \/ as sysdba\ parfileimpdp.par Import: Release 11.2.0.4.0 - Production on Fri Apr 16 10:57:13 2021Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.Connected to: Oracle Database 11g Ente…

VS-RK3399性能介绍

VS-RK3399采用6核64位处理器&#xff0c;主频1.8Ghz。GPU采用Mali-T860 GPU, OpenGL ES1.1/2.0/3.0/3.1, OpenVG1.1, OpenCL,DX11等规范。 搭载嵌入式Android 7.1版本系统,板载DDR3 2GB内存, 并可支持3G/4G通信模块扩展&#xff0c;HDMIEDPMIPI显示输出(支持1080P) 板载16GB NA…

DFB激光器电流温度与波长的关系

电流增加&#xff0c;波长增加&#xff0c;温度电压增加&#xff0c;温度降低&#xff0c;波长减小 图里面是温度的电压&#xff0c;不是温度&#xff0c;所以随着温度电压&#xff08;热敏电阻电压&#xff09;的增大&#xff0c;温度降低&#xff0c;波长减小 DFB激光器-北京…

rtx3090显卡什么级别 rtx3090显卡什么水平 3090属于什么档次的显卡

3090是最强显卡 3090全称&#xff1a;RTX 3090显卡&#xff0c;2020年9月2日正式发布。搭载24GB GDDR6X显存&#xff0c;采用三插槽体积&#xff0c;双轴流线型散热器设计。rtx3090怎么样这些点很重要 http://www.adiannao.cn/dq 2、RTX 3090显卡与上一代RTX 3080显卡对比&…

NVIDIA GeForce GT 730 配置 CUDA

1.下 cuda toolkit 8.0 CUDA Toolkit 8.0 GA1 Download | NVIDIA Developer 2.下 cuDNN 6.0 cuDNN Archive | NVIDIA Developer 3. 把 cuDNN 里的 bin、include、lib 里的东西放到 C:Program FilesNVIDIA GPU Computing ToolkitCUDAv8.0 相应文件夹里 4. 5. conda instal…

R中报错Error in idx[i, ] <- res[[i]][[1]] : number of items to replace is not a multiple of

运行predictions.assay <- TransferData(anchorset anchors, refdata allen_reference$cell_type, prediction.assay TRUE, weight.reduction ca_6[["pca"]], dims 1:30)时 报错Error in idx[i, ] <- res[[i]][[1]] : n…

ORA-39002 ORA-39358 错误处理方法

问题说明 在做数据库还原时出现ORA-39002 和 ORA-39358 错误&#xff0c;具体信息如下&#xff1a; $ impdp rui/oracle directorydmp_dir dumpfiletest_expdp20210514.dmp logfiletest_impdp202105141.log job_namerui202105141_jobImport: Release 12.1.0.2.0 - Productio…