MyBatis学习笔记-数据脱敏

如果项目需要对一些特殊、敏感的数据进行脱敏处理。根据实际的需求可以考虑在读写的过程中分别做脱敏操作。
一、写过程参数脱敏
主要是使用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;
    }

}

总体来说,数据字段的脱敏操作没有那么复杂,可以根据自身的需求更加细粒度的控制实现。

相关推荐
fat house cat_8 分钟前
【redis】线程IO模型
java·redis
stein_java1 小时前
springMVC-10验证及国际化
java·spring
weixin_478689761 小时前
C++ 对 C 的兼容性
java·c语言·c++
LUCIAZZZ2 小时前
HikariCP数据库连接池原理解析
java·jvm·数据库·spring·springboot·线程池·连接池
sky_ph2 小时前
JAVA-GC浅析(二)G1(Garbage First)回收器
java·后端
IDRSolutions_CN2 小时前
PDF 转 HTML5 —— HTML5 填充图形不支持 Even-Odd 奇偶规则?(第二部分)
java·经验分享·pdf·软件工程·团队开发
hello早上好2 小时前
Spring不同类型的ApplicationContext的创建方式
java·后端·架构
HelloWord~3 小时前
SpringSecurity+vue通用权限系统2
java·vue.js
让我上个超影吧3 小时前
黑马点评【基于redis实现共享session登录】
java·redis
BillKu4 小时前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis