Skip to content

Commit

Permalink
[spring boot] 数据脱敏
Browse files Browse the repository at this point in the history
  • Loading branch information
SunYufei committed Oct 1, 2024
1 parent dde5158 commit 96dd9a7
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 0 deletions.
11 changes: 11 additions & 0 deletions docs/spring/controller/datamark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 数据脱敏

使用注解和自定义序列化器的方式进行数据脱敏

<<< @/../spring-boot-demo/controller/src/main/java/ml/sun/common/annotation/DataMark.kt

<<< @/../spring-boot-demo/controller/src/main/java/ml/sun/common/enums/DataMarkType.kt

<<< @/../spring-boot-demo/controller/src/main/java/ml/sun/common/serializer/DataMarkSerializer.kt

<<< @/../spring-boot-demo/controller/src/main/java/ml/sun/vo/CarInfoVO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ml.sun.common.annotation

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import ml.sun.common.enums.DataMarkType
import ml.sun.common.serializer.DataMarkSerializer

@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@JsonSerialize(using = DataMarkSerializer::class)
@JacksonAnnotationsInside
annotation class DataMark(
val type: DataMarkType = DataMarkType.DEFAULT,
val startIndex: Int = 0,
val endIndex: Int = 0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ml.sun.common.enums

enum class DataMarkType(val func: (String, Int, Int) -> String) {
LICENSE({ text, _, _ -> "${text.substring(0, 2)}*****" }),
MOBILE({ mobile, _, _ -> "${mobile.substring(0, 3)}****${mobile.substring(7, 11)}" }),
ID_CARD({ card, _, _ -> "${card.substring(0, 6)}************" }),
BANK_CARD({ card, _, _ -> "${card.substring(0, 6)}*************" }),
CHINESE_NAME({ name, _, _ -> "${name.substring(0, 1)}${"*".repeat(name.length - 1)}" }),
DEFAULT({ text, _, _ -> text })
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ml.sun.common.serializer

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.BeanProperty
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.ser.ContextualSerializer
import ml.sun.common.annotation.DataMark
import ml.sun.common.enums.DataMarkType

class DataMarkSerializer : JsonSerializer<String>(), ContextualSerializer {
private lateinit var type: DataMarkType
private var startIndex: Int = 0
private var endIndex: Int = 0

fun set(type: DataMarkType, startIndex: Int, endIndex: Int) {
this.type = type
this.startIndex = startIndex
this.endIndex = endIndex
}

override fun serialize(text: String, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(type.func(text, startIndex, endIndex))
}

/**
* 检查是否有 DataMark 注解,数据类型是否为 String
*/
override fun createContextual(provider: SerializerProvider, property: BeanProperty?): JsonSerializer<*> {
// 判断是否为 String 类型
if (property?.type?.rawClass == String::class.java) {
// 获取自定义注解
var annotation = property.getAnnotation(DataMark::class.java)
if (annotation == null) {
annotation = property.getContextAnnotation(DataMark::class.java)
}
// 标注数据脱敏
return if (annotation != null) {
val serializer = DataMarkSerializer()
serializer.set(annotation.type, annotation.startIndex, annotation.endIndex)
serializer
} else {
provider.findValueSerializer(property.type, property)
}
}
// 默认序列化器
return provider.findNullValueSerializer(property)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ml.sun.controller

import ml.sun.vo.CarInfoVO
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("car")
class CarController {
@GetMapping("info")
fun info() = CarInfoVO(
"鲁A99999",
"13100000000",
"370000190001010000",
"6220000000000000000",
"张三"
)
}
12 changes: 12 additions & 0 deletions spring-boot-demo/controller/src/main/java/ml/sun/vo/CarInfoVO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ml.sun.vo

import ml.sun.common.annotation.DataMark
import ml.sun.common.enums.DataMarkType

data class CarInfoVO(
@DataMark(DataMarkType.LICENSE) val license: String,
@DataMark(DataMarkType.MOBILE) val mobile: String,
@DataMark(DataMarkType.ID_CARD) val idCard: String,
@DataMark(DataMarkType.BANK_CARD) val bankCard: String,
@DataMark(DataMarkType.CHINESE_NAME) val owner: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ml.sun.controller

import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.get

@WebMvcTest(CarController::class)
class CarControllerTest {
@Autowired
private lateinit var mockMvc: MockMvc

@Test
fun info() {
mockMvc.get("/car/info").andExpect {
status { isOk() }
jsonPath("data.license") { value("鲁A*****") }
jsonPath("data.mobile") { value("131****0000") }
jsonPath("data.idCard") { value("370000************") }
jsonPath("data.bankCard") { value("622000*************") }
jsonPath("data.owner") { value("张*") }
}.andDo { print() }
}
}

0 comments on commit 96dd9a7

Please sign in to comment.