mirror of https://github.com/jeecgboot/jeecg-boot
优化数据脱敏功能
parent
f6a3e11aa2
commit
ae1b8d4654
|
@ -0,0 +1,87 @@
|
|||
package org.jeecg.common.desensitization;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.BeanProperty;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveField;
|
||||
import org.jeecg.common.desensitization.enums.SensitiveEnum;
|
||||
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
|
||||
import org.jeecg.common.util.encryption.AesEncryptUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/6/19 10:43
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class SensitiveFieldSerialize extends JsonSerializer<String> implements ContextualSerializer {
|
||||
|
||||
private SensitiveEnum type;
|
||||
|
||||
@Override
|
||||
public void serialize(String data, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||
switch (type){
|
||||
case ENCODE:
|
||||
try {
|
||||
jsonGenerator.writeString(AesEncryptUtil.encrypt(data));
|
||||
} catch (Exception exception) {
|
||||
log.error("数据加密错误", exception.getMessage());
|
||||
jsonGenerator.writeString(data);
|
||||
}
|
||||
break;
|
||||
case CHINESE_NAME:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.chineseName(data));
|
||||
break;
|
||||
case ID_CARD:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.idCardNum(data));
|
||||
break;
|
||||
case FIXED_PHONE:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.fixedPhone(data));
|
||||
break;
|
||||
case MOBILE_PHONE:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.mobilePhone(data));
|
||||
break;
|
||||
case ADDRESS:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.address(data, 3));
|
||||
break;
|
||||
case EMAIL:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.email(data));
|
||||
break;
|
||||
case BANK_CARD:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.bankCard(data));
|
||||
break;
|
||||
case CNAPS_CODE:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.cnapsCode(data));
|
||||
break;
|
||||
default:
|
||||
jsonGenerator.writeString(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
|
||||
if (beanProperty != null) {
|
||||
if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
|
||||
SensitiveField sensitive = beanProperty.getAnnotation(SensitiveField.class);
|
||||
if (sensitive == null) {
|
||||
sensitive = beanProperty.getContextAnnotation(SensitiveField.class);
|
||||
}
|
||||
if (sensitive != null) {
|
||||
return new SensitiveFieldSerialize(sensitive.type());
|
||||
}
|
||||
}
|
||||
return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
|
||||
}
|
||||
return serializerProvider.findNullValueSerializer(null);
|
||||
}
|
||||
}
|
|
@ -6,10 +6,12 @@ import java.lang.annotation.*;
|
|||
* 解密注解
|
||||
*
|
||||
* 在方法上定义 将方法返回对象中的敏感字段 解密,需要注意的是,如果没有加密过,解密会出问题,返回原字符串
|
||||
* @deprecated 直接在实体的字段中使用@{@link SensitiveField}即可
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@Deprecated
|
||||
public @interface SensitiveDecode {
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,10 +6,12 @@ import java.lang.annotation.*;
|
|||
* 加密注解
|
||||
*
|
||||
* 在方法上声明 将方法返回对象中的敏感字段 加密/格式化
|
||||
* @deprecated 直接在实体的字段中使用@{@link SensitiveField}即可
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@Deprecated
|
||||
public @interface SensitiveEncode {
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package org.jeecg.common.desensitization.annotation;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import org.jeecg.common.desensitization.SensitiveFieldSerialize;
|
||||
import org.jeecg.common.desensitization.enums.SensitiveEnum;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
@ -11,6 +14,8 @@ import java.lang.annotation.*;
|
|||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@JacksonAnnotationsInside
|
||||
@JsonSerialize(using = SensitiveFieldSerialize.class)
|
||||
public @interface SensitiveField {
|
||||
|
||||
/**
|
||||
|
|
|
@ -198,7 +198,7 @@ public class SensitiveInfoUtil {
|
|||
* @param fullName 全名
|
||||
* @return <例子:李**>
|
||||
*/
|
||||
private static String chineseName(String fullName) {
|
||||
public static String chineseName(String fullName) {
|
||||
if (oConvertUtils.isEmpty(fullName)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ public class SensitiveInfoUtil {
|
|||
* @param firstName 名
|
||||
* @return <例子:李**>
|
||||
*/
|
||||
private static String chineseName(String familyName, String firstName) {
|
||||
public static String chineseName(String familyName, String firstName) {
|
||||
if (oConvertUtils.isEmpty(familyName) || oConvertUtils.isEmpty(firstName)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ public class SensitiveInfoUtil {
|
|||
* @param id 身份证号
|
||||
* @return <例子:*************5762>
|
||||
*/
|
||||
private static String idCardNum(String id) {
|
||||
public static String idCardNum(String id) {
|
||||
if (oConvertUtils.isEmpty(id)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ public class SensitiveInfoUtil {
|
|||
* @param num 固定电话
|
||||
* @return <例子:****1234>
|
||||
*/
|
||||
private static String fixedPhone(String num) {
|
||||
public static String fixedPhone(String num) {
|
||||
if (oConvertUtils.isEmpty(num)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ public class SensitiveInfoUtil {
|
|||
* @param num 手机号码
|
||||
* @return <例子:138******1234>
|
||||
*/
|
||||
private static String mobilePhone(String num) {
|
||||
public static String mobilePhone(String num) {
|
||||
if (oConvertUtils.isEmpty(num)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ public class SensitiveInfoUtil {
|
|||
* @param sensitiveSize 敏感信息长度
|
||||
* @return <例子:北京市海淀区****>
|
||||
*/
|
||||
private static String address(String address, int sensitiveSize) {
|
||||
public static String address(String address, int sensitiveSize) {
|
||||
if (oConvertUtils.isEmpty(address)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ public class SensitiveInfoUtil {
|
|||
* @param email 电子邮箱
|
||||
* @return <例子:g**@163.com>
|
||||
*/
|
||||
private static String email(String email) {
|
||||
public static String email(String email) {
|
||||
if (oConvertUtils.isEmpty(email)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ public class SensitiveInfoUtil {
|
|||
* @param cardNum 银行卡号
|
||||
* @return <例子:6222600**********1234>
|
||||
*/
|
||||
private static String bankCard(String cardNum) {
|
||||
public static String bankCard(String cardNum) {
|
||||
if (oConvertUtils.isEmpty(cardNum)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ public class SensitiveInfoUtil {
|
|||
* @param code 公司开户银行联号
|
||||
* @return <例子:12********>
|
||||
*/
|
||||
private static String cnapsCode(String code) {
|
||||
public static String cnapsCode(String code) {
|
||||
if (oConvertUtils.isEmpty(code)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -326,7 +326,7 @@ public class SensitiveInfoUtil {
|
|||
* @param reservedLength 保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatRight(String str, int reservedLength){
|
||||
public static String formatRight(String str, int reservedLength){
|
||||
String name = str.substring(0, reservedLength);
|
||||
String stars = String.join("", Collections.nCopies(str.length()-reservedLength, "*"));
|
||||
return name + stars;
|
||||
|
@ -338,7 +338,7 @@ public class SensitiveInfoUtil {
|
|||
* @param reservedLength 保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatLeft(String str, int reservedLength){
|
||||
public static String formatLeft(String str, int reservedLength){
|
||||
int len = str.length();
|
||||
String show = str.substring(len-reservedLength);
|
||||
String stars = String.join("", Collections.nCopies(len-reservedLength, "*"));
|
||||
|
@ -352,7 +352,7 @@ public class SensitiveInfoUtil {
|
|||
* @param endLen 结尾保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatBetween(String str, int beginLen, int endLen){
|
||||
public static String formatBetween(String str, int beginLen, int endLen){
|
||||
int len = str.length();
|
||||
String begin = str.substring(0, beginLen);
|
||||
String end = str.substring(len-endLen);
|
||||
|
|
Loading…
Reference in New Issue