字段脱敏注解
注解定义
java
package org.elsfs.cloud.core.annotation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 字段脱敏注解
*
* @author zeng
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
public @interface SensitiveBye {
/**
* 脱敏策略
*
* @return 脱敏策略
*/
SensitiveType strategy() default SensitiveType.CUSTOM;
}
java
package org.elsfs.cloud.core.annotation;
import cn.hutool.core.util.DesensitizedUtil;
import java.util.function.Function;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* 内置脱敏策略
*
* @author zeng
*/
@Getter
@RequiredArgsConstructor
public enum SensitiveType {
/** 中文名字的敏感信息处理方式 */
CHINESE_NAME(SensitiveByeHandle.CHINESE_NAME),
/** 身份证号的敏感信息处理方式 */
ID_CARD(SensitiveByeHandle.ID_CARD),
/** 密码的敏感信息处理方式 */
PASSWORD(SensitiveByeHandle.PASSWORD),
/** 手机号的敏感信息处理方式 */
MOBILE(SensitiveByeHandle.MOBILE),
/** 电话号码的敏感信息处理方式 */
PHONE(SensitiveByeHandle.PHONE),
/** 电子邮件地址的敏感信息处理方式 */
EMAIL(SensitiveByeHandle.EMAIL),
/** 地址的敏感信息处理方式 */
ADDRESS(SensitiveByeHandle.ADDRESS),
/** 车牌号的敏感信息处理方式 */
CAR_NUMBER(SensitiveByeHandle.CAR_NUMBER),
/** 银行卡号的敏感信息处理方式 */
BANK_CARD(SensitiveByeHandle.BANK_CARD),
/** 自定义敏感信息的处理方式 */
CUSTOM(SensitiveByeHandle.CUSTOM);
/** 处理敏感信息的处理器 */
private final SensitiveByeHandle handle;
/**
* 处理方法
*
* @param function 处理方法
*/
public record SensitiveByeHandle(Function<String, String> function) {
/** 中文姓名 */
public static final SensitiveByeHandle CHINESE_NAME =
new SensitiveByeHandle(DesensitizedUtil::chineseName);
/** 身份证号 */
public static final SensitiveByeHandle ID_CARD =
new SensitiveByeHandle(s -> DesensitizedUtil.idCardNum(s, 3, 2));
/** 密码 */
public static final SensitiveByeHandle PASSWORD =
new SensitiveByeHandle(DesensitizedUtil::password);
/** 固话号码 */
public static final SensitiveByeHandle MOBILE =
new SensitiveByeHandle(DesensitizedUtil::fixedPhone);
/** 手机号 */
public static final SensitiveByeHandle PHONE =
new SensitiveByeHandle(DesensitizedUtil::mobilePhone);
/** 邮箱 */
public static final SensitiveByeHandle EMAIL = new SensitiveByeHandle(DesensitizedUtil::email);
/** 地址 */
public static final SensitiveByeHandle ADDRESS =
new SensitiveByeHandle(s -> DesensitizedUtil.address(s, 5));
/** 银行卡号 */
public static final SensitiveByeHandle BANK_CARD =
new SensitiveByeHandle(DesensitizedUtil::bankCard);
/** 车牌号 */
public static final SensitiveByeHandle CAR_NUMBER =
new SensitiveByeHandle(DesensitizedUtil::carLicense);
/** 自定义策略 */
public static final SensitiveByeHandle CUSTOM = new SensitiveByeHandle(s -> s);
}
}
处理敏感信息拦截器
java
package org.elsfs.cloud.core.jackson.serializer;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
import org.elsfs.cloud.core.annotation.SensitiveBye;
/**
* 处理敏感信息
*
* @author zeng
*/
public class SensitiveByeNopAnnotationIntrospector extends NopAnnotationIntrospector {
@Override
public Object findSerializer(Annotated am) {
SensitiveBye annotation = am.getAnnotation(SensitiveBye.class);
if (annotation != null) {
return new SensitiveSerializer(annotation);
}
return null;
}
@Override
public Object findDeserializer(Annotated am) {
return super.findDeserializer(am);
}
}
jackson配置
java
/**
* jackson配置
*
* @author zeng
*/
@Configuration(proxyBeanMethods = false)
public class JacksonConfiguration {
/**
* ObjectMapper自定义配置
*
* @return ObjectMapper Builder
*/
@Bean
Jackson2ObjectMapperBuilderCustomizer objectMapperCustomizer() {
return builder -> {
builder.locale(Locale.CHINA);
builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
builder.serializerByType(Long.class, ToStringSerializer.instance);
builder.modules(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule());
// 覆盖部分
builder.modules(new JavaTimeModule());
builder.annotationIntrospector(new SensitiveByeNopAnnotationIntrospector());
};
}
}
如何使用
定义实体
java
/**
* user
*
* @author zeng
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
private String id;
@SensitiveBye(strategy = SensitiveType.PHONE)
private String phone;
@SensitiveBye(strategy = SensitiveType.CHINESE_NAME)
private String name;
@SensitiveBye(strategy = SensitiveType.ID_CARD)
private String idCard;
@SensitiveBye(strategy = SensitiveType.PASSWORD)
private String password;
@SensitiveBye(strategy = SensitiveType.MOBILE)
private String mobile;
@SensitiveBye(strategy = SensitiveType.EMAIL)
private String email;
@SensitiveBye(strategy = SensitiveType.ADDRESS)
private String address;
@SensitiveBye(strategy = SensitiveType.BANK_CARD)
private String bankCard;
@SensitiveBye(strategy = SensitiveType.CAR_NUMBER)
private String carNumber;
@SensitiveBye(strategy = SensitiveType.CUSTOM)
private String custom;
}
使用ObjectMapper的 bean 或者 new 一个ObjectMapper 并且添加拦截器
java
package org.elsfs.cloud.common.core.jackson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elsfs.cloud.core.jackson.serializer.SensitiveByeNopAnnotationIntrospector;
import org.junit.jupiter.api.Test;
/**
* 测试
*
* @author zeng
*/
@NoArgsConstructor
@Slf4j
public class SensitiveByeTest {
@Test
public void jsonUser() throws JsonProcessingException {
// 添加的'test'自定义策略直接在注解中使用即可:@SensitiveBye("test")
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new SensitiveByeNopAnnotationIntrospector());
final DefaultSerializerProvider.Impl provider = new DefaultSerializerProvider.Impl();
objectMapper.setSerializerProvider(provider);
final User user =
User.builder()
.id("123")
.phone("13212341234")
.name("你好")
.idCard("522322188012120123")
.password("123456")
.mobile("010-88880000")
.email("abc@163.com")
.address("北京市朝阳区十里堡123号")
.bankCard("622312312341234123")
.carNumber("京A-1234567")
.custom("test自定义")
.build();
final String string = objectMapper.writeValueAsString(user);
LOGGER.warn(string);
}
}