無論對于什么業務來說,用戶資料資訊的安全性無疑都是非常重要的,尤其是在數字經濟大火背景下,資料的安全性就顯得更加重要,資料脫敏可以分為兩個部分,一個是DB層面,防止DB資料泄露,暴露用戶資訊;一個是介面層面,有些UI展示需要資料脫敏,防止用戶資訊被人刷走了,
v需求背景
DB層面的脫敏今天先不講,今天先講講依賴于注解的介面層面的資料脫敏,介面層面的脫敏可能最原始和簡單的方法就是在每個controller輸出資料時,硬性處理,但是這么做的方案,如果后續脫敏規則改了,那需要改的地方就太多了,而且很容易有遺漏的地方,造成全站脫敏規則不統一的情況,所以我們建議的是用注解的方式,可插拔性更好,隨時可以更改規則,更加的靈活,
我們今天接到的需求是這樣的:

頁面或者介面層面的脫敏,大多也是圍繞用戶手機號啊、真實姓名或者地址等等展開的,
v架構設計
2.1 脫敏欄位列舉:SensitivityEnum這里定義一個敏感欄位的列舉,并設定各個欄位的脫敏策略,
/** * @Author tou tou * @Date 2023/1/15 * @Des 脫敏型別及策略,不同的欄位型別適配不同的策略 */ public enum SensitivityEnum { /** * 用戶名 */ USERNAME(s -> s.replaceAll("\\S*(\\S)", "***$1")), /** * 身份證 */ ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")), /** * 手機號 */ PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), /** * 地址 */ ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****")); private final Function<String, String> desensitizer; SensitivityEnum(Function<String, String> desensitizer) { this.desensitizer = desensitizer; } public Function<String, String> desensitizer() { return desensitizer; } }2.2 創建自定義隱私注解:Sensitivity
都說了,我們使用的是注解的方式脫敏,所以是需要宣告一個脫敏注解的,需要用到的地方,按需宣告注解即可,非常方便,
/** * @Author tou tou * @Date 2023/1/15 * @Des */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using = SensitivitySerializer.class) public @interface Sensitivity { SensitivityEnum strategy(); }2.3 創建序列化類:SensitivitySerializer
/** * @Author tou tou * @Date 2023/1/15 * @Des */ public class SensitivitySerializer extends JsonSerializer<String> implements ContextualSerializer { private SensitivityEnum sensitivityEnum; @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(sensitivityEnum.desensitizer().apply(value)); } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { Sensitivity annotation = property.getAnnotation(Sensitivity.class); if (Objects.nonNull(annotation)&&Objects.equals(String.class, property.getType().getRawClass())) { this.sensitivityEnum = annotation.strategy(); return this; } return prov.findValueSerializer(property.getType(), property); } }2.4 使用了
@Sensitivity注解的物體類
public class UserAccountVO { private Integer id; @Sensitivity(strategy = SensitivityEnum.USERNAME) private String username; private Integer age; @Sensitivity(strategy = SensitivityEnum.PHONE) private String tel; private String email; private String account; }2.5 插入mysql測驗資料
create table useraccount ( id INT(11), username NVARCHAR(25), age INT(11), phone bigint, email VARCHAR(80), account VARCHAR(20), pwd VARCHAR(20) ); select * from useraccount; insert into useraccount values(1,'張老三', 22, 13555551111,'[email protected]','z13555551111', '13555551111');2.6 測驗介面
/** * @author toutou * @date by 2019/07 */ @RestController public class UserController { @Autowired UserAccountService userAccountService; @GetMapping("/user/getuser") public Result getUserAccountById(@RequestParam("uid") int id){ UserAccountVO user = userAccountService.getUserAccountById(id); if(user != null){ return Result.setSuccessResult(user); }else{ return Result.setErrorResult(404, "用戶不存在"); } } }
v運行效果

v原始碼地址
https://github.com/toutouge/javademosecond/tree/master/hellolearn
作 者:請叫我頭頭哥
出 處:http://www.cnblogs.com/toutou/
關于作者:專注于基礎平臺的專案開發,如有問題或建議,請多多賜教!
著作權宣告:本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文鏈接,
特此宣告:所有評論和私信都會在第一時間回復,也歡迎園子的大大們指正錯誤,共同進步,或者直接私信我
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角【推薦】一下,您的鼓勵是作者堅持原創和持續寫作的最大動力!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548901.html
標籤:其他
上一篇:Java面向物件--介面和多型
