SpringBoot實(shí)現(xiàn)接口返回?cái)?shù)據(jù)脫敏的代碼示例
引言
在當(dāng)今的信息化時(shí)代,數(shù)據(jù)安全尤為重要。接口返回?cái)?shù)據(jù)脫敏是一種重要的數(shù)據(jù)保護(hù)手段,可以防止敏感信息通過(guò)接口返回給客戶端,降低數(shù)據(jù)泄露的風(fēng)險(xiǎn)。本文旨在探討如何在SpringBoot應(yīng)用程序中實(shí)現(xiàn)接口返回?cái)?shù)據(jù)脫敏。我們將介紹一種基于自定義注解結(jié)合Hutool脫敏工具類的方案,以實(shí)現(xiàn)SpringBoot中的接口返回?cái)?shù)據(jù)脫敏。
一、接口數(shù)據(jù)脫敏概述
1.1 接口數(shù)據(jù)脫敏的定義
接口數(shù)據(jù)脫敏是指在Web應(yīng)用程序的API接口返回?cái)?shù)據(jù)時(shí),對(duì)包含敏感信息的字段進(jìn)行處理,使其部分或全部信息被隱藏或替換,以防止敏感信息的泄露。這個(gè)過(guò)程通常不會(huì)改變數(shù)據(jù)的原始格式,而是通過(guò)特定的算法或規(guī)則,將敏感部分替換為特定字符(如星號(hào)*)或者保留部分信息。
1.2 接口數(shù)據(jù)脫敏的重要性
數(shù)據(jù)脫敏的重要性主要體現(xiàn)在以下幾個(gè)方面:
- 保護(hù)用戶隱私: 對(duì)于姓名、身份證號(hào)、手機(jī)號(hào)等個(gè)人敏感信息進(jìn)行脫敏,可以有效保護(hù)用戶隱私,防止信息被濫用。
- 遵守法律法規(guī): 許多國(guó)家和地區(qū)都制定了嚴(yán)格的數(shù)據(jù)保護(hù)法規(guī),如歐盟的GDPR和中國(guó)的《個(gè)人信息保護(hù)法》。實(shí)施數(shù)據(jù)脫敏有助于企業(yè)合規(guī)經(jīng)營(yíng)。
- 降低安全風(fēng)險(xiǎn): 通過(guò)脫敏處理,即使數(shù)據(jù)不慎泄露,也能最大限度地減少敏感信息被盜用的風(fēng)險(xiǎn)。
- 支持?jǐn)?shù)據(jù)共享: 在保護(hù)隱私的同時(shí),脫敏數(shù)據(jù)仍然保留了一定的分析價(jià)值,有利于數(shù)據(jù)的安全共享和利用。
1.3 接口數(shù)據(jù)脫敏的實(shí)現(xiàn)方式
手動(dòng)脫敏:在業(yè)務(wù)邏輯層直接對(duì)敏感數(shù)據(jù)進(jìn)行處理。這種方式靈活但容易遺漏,且代碼重復(fù)率高。
AOP(面向切面編程):通過(guò)切面攔截返回?cái)?shù)據(jù),統(tǒng)一處理敏感字段。這種方式可以集中管理脫敏邏輯,但可能影響性能。
自定義序列化器:利用JSON序列化框架(如Jackson)的自定義序列化器來(lái)處理敏感字段。這種方式性能較好,且與業(yè)務(wù)邏輯解耦。
注解+反射:通過(guò)自定義注解標(biāo)記需要脫敏的字段,然后利用反射機(jī)制在運(yùn)行時(shí)進(jìn)行脫敏處理。這種方式使用簡(jiǎn)單,易于維護(hù)。
本文將重點(diǎn)介紹如何結(jié)合自定義注解和Hutool工具類來(lái)實(shí)現(xiàn)接口數(shù)據(jù)脫敏。
二、開發(fā)環(huán)境
- JDK版本:JDK 17
- Spring Boot版本:Spring Boot 3.2.2
- 構(gòu)建工具:Maven
三、實(shí)現(xiàn)接口返回?cái)?shù)據(jù)脫敏
3.1 添加依賴
首先在 pom.xml
文件中添加必要的依賴:
<!-- Hutool工具包 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.25</version> </dependency> <!-- Jackson依賴 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.2</version> </dependency>
3.2 創(chuàng)建自定義注解
接下來(lái),我們創(chuàng)建一個(gè)自定義注解 @Desensitize
:
/** * 用于標(biāo)記字段需要進(jìn)行脫敏處理的注解 * * @author shijun * @date 2024/07/09 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using = DesensitizeSerializer.class) public @interface Desensitize { /** * 脫敏類型 */ DesensitizeType type() default DesensitizeType.DEFAULT; /** * 脫敏起始位置 */ int startInclude() default 0; /** * 脫敏結(jié)束位置 */ int endExclude() default 0; }
3.3 定義脫敏枚舉類
然后,定義枚舉類 DesensitizeType
來(lái)定義字段的脫敏類型:
/** * 脫敏類型枚舉類 */ public enum DesensitizeType { /** * 默認(rèn)脫敏 */ DEFAULT, /** * 自定義脫敏 */ CUSTOM_RULE, /** * 手機(jī)號(hào)脫敏 */ PHONE, /** * 電子郵件脫敏 */ EMAIL, /** * 身份證號(hào)脫敏 */ ID_CARD, /** * 銀行卡號(hào)脫敏 */ BANK_CARD, /** * 地址脫敏 */ ADDRESS, /** * 中文姓名脫敏 */ CHINESE_NAME, /** * 密碼脫敏 */ PASSWORD, }
3.4 創(chuàng)建自定義序列化類
Hutool支持的脫敏數(shù)據(jù)類型包括:
- 用戶id
- 中文姓名
- 身份證號(hào)
- 座機(jī)號(hào)
- 手機(jī)號(hào)
- 地址
- 電子郵件
- 密碼
- 中國(guó)大陸車牌,包含普通車輛、新能源車輛
- 銀行卡
整體來(lái)說(shuō),所謂脫敏就是隱藏掉信息中的一部分關(guān)鍵信息,用*
代替。大家可以自己看一看DesensitizedUtil
類中方法,其實(shí)就是replace
方法和hide
方法的使用,想要自定義規(guī)則進(jìn)行隱藏可以仿照進(jìn)行實(shí)現(xiàn)。
/** * 脫敏序列化器,用于在序列化字符串時(shí)根據(jù)不同的脫敏類型進(jìn)行數(shù)據(jù)脫敏。 * * @author shijun * @date 2024/07/08 */ public class DesensitizeSerializer extends JsonSerializer<String> implements ContextualSerializer { /** * 脫敏類型,默認(rèn)為DEFAULT */ private DesensitizeType type; /** * 脫敏起始位置 */ private int startInclude; /** * 脫敏結(jié)束位置 */ private int endExclude; public DesensitizeSerializer() { this.type = DesensitizeType.DEFAULT; } public DesensitizeSerializer(DesensitizeType type) { this.type = type; } /** * 序列化字符串時(shí)調(diào)用,根據(jù)脫敏類型對(duì)字符串進(jìn)行相應(yīng)的脫敏處理。 * * @param value 待序列化的字符串 * @param gen JSON生成器,用于寫入處理后的字符串 * @param serializers 序列化器提供者,用于獲取其他序列化器 * @throws IOException 如果序列化過(guò)程中發(fā)生I/O錯(cuò)誤 */ @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { switch (type) { case CUSTOM_RULE: // 這里是對(duì)字符串的startInclude到endExclude字段進(jìn)行隱藏處理,如果想要實(shí)現(xiàn)兩端保留,可以考慮使用StrUtil的replace方法 gen.writeString(StrUtil.hide(value, startInclude, endExclude)); break; case PHONE: gen.writeString(DesensitizedUtil.mobilePhone(value)); break; case EMAIL: gen.writeString(DesensitizedUtil.email(value)); break; case ID_CARD: gen.writeString(DesensitizedUtil.idCardNum(value, 1, 2)); break; case BANK_CARD: gen.writeString(DesensitizedUtil.bankCard(value)); break; case ADDRESS: gen.writeString(DesensitizedUtil.address(value, 8)); break; case CHINESE_NAME: gen.writeString(DesensitizedUtil.chineseName(value)); break; case PASSWORD: gen.writeString(DesensitizedUtil.password(value)); break; default: gen.writeString(value); break; } } /** * 根據(jù)上下文信息創(chuàng)建自定義的序列化器,用于處理帶有@Desensitize注解的屬性。 * * @param prov 序列化器提供者,用于獲取其他序列化器 * @param property 當(dāng)前屬性的信息,用于獲取注解和屬性類型 * @return 自定義的序列化器實(shí)例 */ @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) { if (property != null) { Desensitize annotation = property.getAnnotation(Desensitize.class); if (annotation != null) { this.type = annotation.type(); if (annotation.type() == DesensitizeType.CUSTOM_RULE) { this.startInclude = annotation.startInclude(); this.endExclude = annotation.endExclude(); } } } return this; } }
代碼分析:
- serialize方法在序列化字符串時(shí)被調(diào)用,根據(jù)脫敏類型對(duì)字符串進(jìn)行相應(yīng)的脫敏處理。根據(jù)不同的脫敏類型,使用不同的處理方法對(duì)字符串進(jìn)行脫敏,并將處理后的字符串寫入JSON生成器中。
- createContextual方法根據(jù)上下文信息創(chuàng)建自定義的序列化器,用于處理帶有@Desensitize注解的屬性。它通過(guò)獲取注解中的脫敏類型和自定義規(guī)則的起始位置和結(jié)束位置,對(duì)實(shí)例進(jìn)行相應(yīng)的設(shè)置,并返回自定義的序列化器實(shí)例。
這個(gè)序列化器的主要用途是在 JSON 序列化過(guò)程中自動(dòng)對(duì)標(biāo)記了 @Desensitize 注解的字段進(jìn)行脫敏處理。
四、測(cè)試
4.1 編寫測(cè)試代碼
- 編寫實(shí)體類
@Data public class UserDTO { /** * 用戶姓名 */ @Desensitize(type = DesensitizeType.CHINESE_NAME) private String name; /** * 用戶手機(jī)號(hào) */ @Desensitize(type = DesensitizeType.PHONE) private String phoneNumber; /** * 用戶電子郵件地址 */ @Desensitize(type = DesensitizeType.EMAIL) private String email; /** * 用戶密碼 */ @Desensitize(type = DesensitizeType.PASSWORD) private String password; /** * 用戶身份證號(hào)碼 */ @Desensitize(type = DesensitizeType.ID_CARD) private String idCard; /** * 用戶銀行卡號(hào) */ @Desensitize(type = DesensitizeType.BANK_CARD) private String bankCard; /** * 用戶地址 */ @Desensitize(type = DesensitizeType.ADDRESS) private String address; /** * 游戲名稱 */ @Desensitize(type = DesensitizeType.CUSTOM_RULE, startInclude = 2, endExclude = 6) private String gameName; }
- 編寫測(cè)試接口
@RestController @RequestMapping("/test") public class TestController { @GetMapping("/desensitize") public UserDTO getUser() { UserDTO userDTO = new UserDTO(); userDTO.setName("孫大圣"); userDTO.setEmail("shijun@163.com"); userDTO.setPhoneNumber("12345678901"); userDTO.setPassword("123456"); userDTO.setAddress("遼寧省盤錦市興隆臺(tái)區(qū)紅村鄉(xiāng)441號(hào)"); userDTO.setIdCard("447465200912089605"); userDTO.setBankCard("6217000000000000000"); userDTO.setGameName("超級(jí)無(wú)敵大鐵錘"); return userDTO; } }
4.2 測(cè)試
五、總結(jié)
在本文中,我們探討了在SpringBoot應(yīng)用程序中實(shí)現(xiàn)數(shù)據(jù)脫敏的重要性,并提出了通過(guò)自定義注解結(jié)合Hutool脫敏工具類實(shí)現(xiàn)數(shù)據(jù)脫敏的解決方案。通過(guò)這個(gè)方案,我們能夠有效地對(duì)敏感數(shù)據(jù)進(jìn)行脫敏處理,從而保護(hù)用戶隱私和數(shù)據(jù)安全,希望對(duì)大家有所幫助。
以上就是SpringBoot實(shí)現(xiàn)接口返回?cái)?shù)據(jù)脫敏的代碼示例的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot接口數(shù)據(jù)脫敏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Java如何在CompletableFuture中實(shí)現(xiàn)日志記錄
這篇文章主要為大家詳細(xì)介紹了一種slf4j自帶的MDC類,來(lái)記錄完整的請(qǐng)求日志,和在CompletableFuture異步線程中如何保留鏈路id,需要的可以參考一下2023-04-04項(xiàng)目依賴Springboot jar失敗解決方案
這篇文章主要介紹了項(xiàng)目依賴Springboot jar失敗解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08Java 實(shí)戰(zhàn)范例之線上婚紗攝影預(yù)定系統(tǒng)的實(shí)現(xiàn)
讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+javaweb+SSM+springboot+mysql實(shí)現(xiàn)一個(gè)線上婚紗攝影預(yù)定系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2021-11-11mybatis plus開發(fā)過(guò)程中遇到的問(wèn)題記錄及解決
這篇文章主要介紹了mybatis plus開發(fā)過(guò)程中遇到的問(wèn)題記錄及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07讀取Java文件到byte數(shù)組的三種方法(總結(jié))
下面小編就為大家?guī)?lái)一篇讀取Java文件到byte數(shù)組的三種方法(總結(jié))。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08