基于java實(shí)現(xiàn)一個(gè)脫敏組件
功能說(shuō)明
因?yàn)樽罱忻撁舻男枨?,所以就趁著這個(gè)機(jī)會(huì)自己實(shí)現(xiàn)了一個(gè)??隙ㄟ€有不少開(kāi)源庫(kù)有這種功能,但是考慮到不一定滿足自己的需要,所以就自己造了一個(gè)輪子自己用。主要功能包括
- 接口返回內(nèi)容的脫敏,包含json序列化方式和aop的兩種實(shí)現(xiàn)。
- json序列化方式只能用于接口數(shù)據(jù)返回,在程序內(nèi)部和數(shù)據(jù)庫(kù)并不脫敏。
- aop的方式,在程序內(nèi)部和接口數(shù)據(jù)返回時(shí)可以脫敏,但是數(shù)據(jù)庫(kù)不脫敏,且速度是慢于序列化方式的。
- 根據(jù)自己的需求來(lái)實(shí)現(xiàn)脫敏規(guī)則,比如有些人的手機(jī)號(hào)脫敏是中間四位,有些人又只保留初始和末尾一位。
- 自定義脫敏字符,默認(rèn)為
*
。 - 請(qǐng)求體數(shù)據(jù)自動(dòng)過(guò)濾,比如你傳向前端的數(shù)據(jù)是包含脫敏字符的,正常的做法是前端判斷時(shí)候包含脫敏字符,如果包含則該字段不往后端傳輸。我這邊實(shí)現(xiàn)的是,如果請(qǐng)求體傳過(guò)來(lái)的數(shù)據(jù)內(nèi)容跟改字段的脫敏規(guī)則一致則不接收該字段內(nèi)容,不,準(zhǔn)確的說(shuō)是在接收該字段內(nèi)容之前轉(zhuǎn)為null。
使用示例
總共有四種使用場(chǎng)景:
1.作用與方法上的aop注解
@Desensitizes({@Desensitize(field = "username", exclude = true), @Desensitize(field = "phoneNumber", type = MobilePhoneDesensitizer.class), @Desensitize(field = "email", type = EmailDesensitizer.class, maskChar = "#")}) @GetMapping("/testMethodAnno") public TestNoAnnoVO testMethodAnno() { TestNoAnnoVO test = new TestNoAnnoVO(); test.setUsername("JohnDoe"); test.setPhoneNumber("13812345678"); test.setEmail("john.doe@example.com"); return test; } @Data public class TestNoAnnoVO { private String username; private String phoneNumber; private String email; }
輸出內(nèi)容為:
2.作用于實(shí)體字段的aop注解
@GetMapping("/testFieldAnno") public TestVO testFieldAnno() { TestVO test = new TestVO(); test.setUsername("JohnDoe"); test.setPhoneNumber("13812345678"); test.setEmail("john.doe@example.com"); test.setIdCard("123456199001011234"); return test; } public class TestVO { @Desensitize(exclude = true) private String username; @Desensitize(type = MobilePhoneDesensitizer.class) private String phoneNumber; @Desensitize(type = EmailDesensitizer.class, maskChar = "#") private String email; @Desensitize(type = IDCardDesensitizer.class, maskChar = "%") private String idCard; }
輸出內(nèi)容為:
3.序列化注解
@GetMapping("/testJsonAnno") public TestJsonVO testJsonAnno() { TestJsonVO test = new TestJsonVO(); test.setUsername("JohnDoe"); test.setPhoneNumber("13812345678"); test.setEmail("j@example.com"); test.setIdCard("123456199001011234"); return test; } @Data public class TestJsonVO { @JsonDesensitize(exclude = true) private String username; @JsonDesensitize(type = MobilePhoneDesensitizer.class) private String phoneNumber; @JsonDesensitize(type = EmailDesensitizer.class, maskChar = "#") private String email; @JsonDesensitize(type = IDCardDesensitizer.class) private String idCard; }
這個(gè)有些區(qū)別,如果設(shè)置了exclude為true,則直接將返回的該字段隱去。輸出內(nèi)容為:
最后就是基于@JsonDesensitize額外加了一個(gè)屬性ignoreDesensitized,用于判斷是否在接收數(shù)據(jù)時(shí)排除脫敏內(nèi)容。
@PostMapping("testPut") public void testPut(@RequestBody TestDTO testDTO) { log.info("接收到的數(shù)據(jù)內(nèi)容為{}", testDTO.toString()); } @Data public class TestDTO { @JsonDesensitize(exclude = true, ignoreDesensitized = true) private String username; @JsonDesensitize(type = MobilePhoneDesensitizer.class, ignoreDesensitized = true) private String phoneNumber; @JsonDesensitize(type = EmailDesensitizer.class, maskChar = "#", ignoreDesensitized = true) private String email; @JsonDesensitize(type = IDCardDesensitizer.class, ignoreDesensitized = true) private String idCard; }
使用效果為:
這個(gè)是嚴(yán)格按照輸出時(shí)的脫敏匹配的,比如輸出時(shí)手機(jī)號(hào)脫敏內(nèi)容為138****1234
,那么136****4321
則不會(huì)接收,正常沒(méi)有*
的手機(jī)號(hào)或者不符合該規(guī)則的比如13****51234
這種也會(huì)被正常接收。當(dāng)然這個(gè)規(guī)則是可以在項(xiàng)目中自定義的。
使用說(shuō)明
項(xiàng)目地址
github.com/chenqi92/alltobs-desensitization-all 里面包含待引入的jar和demo,因?yàn)閯倢?xiě)完,簡(jiǎn)單測(cè)試了一下不排除有其他bug,有需要可以自己fork一下自己改。后續(xù)我會(huì)在項(xiàng)目中實(shí)際使用,如果發(fā)現(xiàn)有bug會(huì)不斷更新,當(dāng)然也歡迎提issuses。
引入jar
<dependency> <groupId>com.alltobs</groupId> <artifactId>alltobs-desensitization</artifactId> <version>1.0.0</version> </dependency>
工具已經(jīng)上傳到了maven的中央倉(cāng)庫(kù),國(guó)內(nèi)的用戶(hù)可能存在下載困難等問(wèn)題,需要科學(xué)一下。使用國(guó)內(nèi)的阿里等平臺(tái)代理,以我以往經(jīng)驗(yàn)同步過(guò)去起碼要半個(gè)月把。
啟用功能
啟動(dòng)類(lèi)添加注解@EnableAllbsDesensitization
根據(jù)自己使用場(chǎng)景的需要、以及上述示例來(lái)選擇性的添加注解
@Desensitize
@Desensitizes
@JsonDesensitize
自定義在項(xiàng)目中實(shí)現(xiàn)一個(gè)自己需要的脫敏方式
如果你不想用默認(rèn)的脫敏方式,實(shí)際上我也沒(méi)寫(xiě)幾個(gè),后續(xù)應(yīng)該會(huì)接著加。 那么就在你的項(xiàng)目工程中自定義集成BaseDesensitizer
類(lèi)然后自己實(shí)現(xiàn)desensitize
和getDesensitizedRegex
方法即可。 這兩個(gè)方法一個(gè)是用于脫敏規(guī)則,一個(gè)是用于接收數(shù)據(jù)時(shí)判斷是否符合規(guī)則。 具體實(shí)現(xiàn)以身份證號(hào)為例:
package com.alltobs.alltobsdesensitizationdemo.desensitizer; import com.alltobs.desensitization.desensitizer.BaseDesensitizer; import java.util.regex.Pattern; /** * 類(lèi) IDCardDesensitizer * * @author ChenQi * @date 2024/11/11 */public class IDCardDesensitizer extends BaseDesensitizer { @Override public String desensitize(String value, String maskChar) { if (value != null && (value.length() == 15 || value.length() == 18)) { // 脫敏中間部分 int prefixLength = 6; int suffixLength = 4; int maskLength = value.length() - prefixLength - suffixLength; String prefix = value.substring(0, prefixLength); String suffix = value.substring(value.length() - suffixLength); String maskedSection = maskChar.repeat(maskLength); return prefix + maskedSection + suffix; } return value; } @Override public String getDesensitizedRegex(String maskChar) { String escapedMaskChar = Pattern.quote(maskChar); // 身份證號(hào)可能是 15 位或 18 位,這里統(tǒng)一處理 String maskPattern = escapedMaskChar + "+"; return "^\\d{6}" + maskPattern + "\\d{4}$"; } }
以上就是基于java實(shí)現(xiàn)一個(gè)脫敏組件的詳細(xì)內(nèi)容,更多關(guān)于java脫敏組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaWeb中獲取表單數(shù)據(jù)及亂碼問(wèn)題的解決方法
這篇文章主要介紹了JavaWeb中獲取表單數(shù)據(jù)及亂碼問(wèn)題的解決方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11idea啟動(dòng)命令過(guò)長(zhǎng)的問(wèn)題及解決
當(dāng)IDEA啟動(dòng)命令過(guò)長(zhǎng)時(shí),可以通過(guò)修改workspace.xml文件或調(diào)整啟動(dòng)類(lèi)配置來(lái)解決,方案一是在.idea文件或項(xiàng)目目錄中修改workspace.xml;方案二是通過(guò)運(yùn)行配置(run->edit)來(lái)保存啟動(dòng)設(shè)置,這兩種方法都可以有效縮短命令長(zhǎng)度,解決啟動(dòng)錯(cuò)誤2024-09-09解決springmvc關(guān)于前臺(tái)日期作為實(shí)體類(lèi)對(duì)象參數(shù)類(lèi)型轉(zhuǎn)換錯(cuò)誤的問(wèn)題
下面小編就為大家?guī)?lái)一篇解決springmvc關(guān)于前臺(tái)日期作為實(shí)體類(lèi)對(duì)象參數(shù)類(lèi)型轉(zhuǎn)換錯(cuò)誤的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06rabbitmq basicReject/basicNack/basicRecover的區(qū)別及說(shuō)明
這篇文章主要介紹了rabbitmq basicReject/basicNack/basicRecover的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01解決調(diào)用ftpClient.retrieveFileStream(String?remoteFilePath)第二次讀
這篇文章主要給大家介紹了關(guān)于如何解決調(diào)用ftpClient.retrieveFileStream(String?remoteFilePath)第二次讀取為空問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08java基礎(chǔ)之TreeMap實(shí)現(xiàn)類(lèi)全面詳解
這篇文章主要為大家介紹了java基礎(chǔ)之TreeMap實(shí)現(xiàn)類(lèi)全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12詳解Java線程池如何統(tǒng)計(jì)線程空閑時(shí)間
這篇文章主要和大家分享一個(gè)面試題:Java線程池是怎么統(tǒng)計(jì)線程空閑時(shí)間?文中的示例代碼講解詳細(xì),對(duì)我們掌握J(rèn)ava有一定幫助,需要的可以參考一下2022-11-11Java中checkbox實(shí)現(xiàn)跨頁(yè)多選的方法
最近做了一個(gè)項(xiàng)目其中遇到這樣的需求,要實(shí)現(xiàn)checkbox跨頁(yè)多選功能,經(jīng)過(guò)小編整理,順利解決,今天小編給大家分享Java中checkbox實(shí)現(xiàn)跨頁(yè)多選的方法,需要的的朋友參考下2017-01-01