goupan
2024-04-03 5506e9a45e717ffcb67ec313b5a4e8206d9b3a39
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package cn.stylefeng.roses.kernel.security.database.interceptor;
 
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.security.database.algorithm.EncryptAlgorithmApi;
import cn.stylefeng.roses.kernel.security.database.annotation.EncryptField;
import cn.stylefeng.roses.kernel.security.database.annotation.ProtectedData;
import cn.stylefeng.roses.kernel.security.database.annotation.ProtectedField;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.util.Properties;
 
/**
 * Mybatis拦截器,拦截入库参数
 *
 * @author majianguo
 * @date 2021/7/3 11:58
 */
@Slf4j
@Component
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class),})
public class ParameterInterceptor implements Interceptor {
 
    @Resource
    private EncryptAlgorithmApi encryptAlgorithmApi;
 
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
 
        // 若指定ResultSetHandler ,这里则能强转为ResultSetHandler
        ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();
 
        // 获取参数对像,即 mapper 中 paramsType 的实例
        Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject");
        parameterField.setAccessible(true);
 
        // 取出实例
        Object parameterObject = parameterField.get(parameterHandler);
        if (parameterObject != null) {
            Class<?> parameterObjectClass = parameterObject.getClass();
 
            // 校验该实例的类是否被@ProtectedData所注解
            ProtectedData protectedData = AnnotationUtils.findAnnotation(parameterObjectClass, ProtectedData.class);
            if (ObjectUtil.isNotNull(protectedData)) {
 
                //取出当前当前类所有字段
                Field[] declaredFields = parameterObjectClass.getDeclaredFields();
 
                // 处理需要加密的字段
                for (Field declaredField : declaredFields) {
 
                    // 包含其中任意一个即可
                    ProtectedField protectedField = declaredField.getAnnotation(ProtectedField.class);
                    EncryptField encryptField = declaredField.getAnnotation(EncryptField.class);
                    if (ObjectUtil.isNotNull(protectedField) || ObjectUtil.isNotNull(encryptField)) {
                        declaredField.setAccessible(true);
                        Object fieldData = declaredField.get(parameterObject);
                        // 如果是String就处理
                        if (fieldData instanceof String) {
                            String value = (String) fieldData;
                            try {
                                String encrypt = encryptAlgorithmApi.encrypt(value);
                                declaredField.set(parameterObject, encrypt);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
        return invocation.proceed();
    }
 
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
 
    @Override
    public void setProperties(Properties properties) {
 
    }
}