如果项目需要对一些特殊、敏感的数据进行脱敏处理。根据实际的需求可以考虑在读写的过程中分别做脱敏操作。
一、写过程参数脱敏
主要是使用mybatis框架提供的Interceptor实现。需要考虑不同类型的参数解析处理方式不同。
java
@Slf4j
@AllArgsConstructor
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class)})
public class ParameterDesensitizationInterceptor extends ParameterInterceptor implements Interceptor {
private final DesensitizationProperties desensitizationProperties;
@Override
public Object intercept(Invocation invocation) throws Throwable {
return handleInvocation(invocation);
}
@Override
public Map<String, List<String>> getObjectFieldsMap() {
return desensitizationProperties.getObjectFieldsMap();
}
@Override
public Object handleObjectField(Object objectFieldValue) {
// 暂时只处理字符串类型
return StringUtils.mask(String.valueOf(objectFieldValue), desensitizationProperties.getStartPosition(),
desensitizationProperties.getEndPosition(), desensitizationProperties.getMaskChar());
}
}
java
@Slf4j
public abstract class ParameterInterceptor extends AbstractInterceptor {
/**
* handle invocation
* @param invocation
* @return
* @throws Throwable
*/
protected Object handleInvocation(Invocation invocation) throws Throwable {
ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();
MetaObject metaObject = MetaObject.forObject(parameterHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
Object parameterObject = parameterHandler.getParameterObject();
if (null == parameterObject) {
return invocation.proceed();
}
Class<Object> parameterizedType = getParameterizedType((MappedStatement) metaObject.getValue("mappedStatement"));
List<String> fields = getObjectFieldsMap().get(parameterizedType.getName());
if (null == fields || fields.isEmpty()) {
return invocation.proceed();
}
if (parameterObject instanceof Map) {
Map<String, Object> parameterMapObject = (Map<String, Object>) parameterObject;
if (parameterMapObject.containsKey(com.baomidou.mybatisplus.core.toolkit.Constants.ENTITY)) {
// handle entity object
Object etObject = parameterMapObject.get(com.baomidou.mybatisplus.core.toolkit.Constants.ENTITY);
if (null != etObject) {
handleObjectFields(etObject);
}
} if (parameterMapObject.containsKey(com.baomidou.mybatisplus.core.toolkit.Constants.WRAPPER)) {
// handle wrapper object
handleObjectFields(metaObject, fields);
} else {
// handle map object
handleObjectFields(parameterizedType, parameterMapObject);
}
} else {
handleObjectFields(parameterObject);
}
return invocation.proceed();
}
}
二、读过程结果脱敏
主要是使用mybatis框架提供的Interceptor实现。
java
@Slf4j
@AllArgsConstructor
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = Statement.class)})
public class ResultSetDesensitizationInterceptor extends ResultSetInterceptor implements Interceptor {
private final DesensitizationProperties desensitizationProperties;
@Override
public Object intercept(Invocation invocation) throws Throwable {
return handleInvocation(invocation);
}
@Override
public Map<String, List<String>> getObjectFieldsMap() {
return desensitizationProperties.getObjectFieldsMap();
}
@Override
public Object handleObjectField(Object objectFieldValue) {
// 暂时只处理字符串类型
return StringUtils.mask(String.valueOf(objectFieldValue), desensitizationProperties.getStartPosition(),
desensitizationProperties.getEndPosition(), desensitizationProperties.getMaskChar());
}
}
java
@Slf4j
public abstract class ResultSetInterceptor extends AbstractInterceptor {
/**
* handle invocation
* @param invocation
* @return
* @throws Throwable
*/
protected Object handleInvocation(Invocation invocation) throws Throwable {
Object proceed = invocation.proceed();
if (null == proceed) {
return null;
}
if (proceed instanceof List) {
((List<?>) proceed).forEach(this::handleObjectFields);
} else {
handleObjectFields(proceed);
}
return proceed;
}
}
总体来说,数据字段的脱敏操作没有那么复杂,可以根据自身的需求更加细粒度的控制实现。