mitao
2025-02-21 31573d6180d15ef65ed0df9c2732495f40b12663
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package com.panzhihua.service_grid.model.helper.encrypt;
 
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
 
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
 
import com.panzhihua.common.model.helper.encrypt.EncryptDecryptClass;
import com.panzhihua.common.model.helper.encrypt.EncryptQuery;
import com.panzhihua.common.model.helper.encrypt.EncryptQueryClass;
import com.panzhihua.common.model.helper.encrypt.IEncryptDecrypt;
 
import lombok.extern.slf4j.Slf4j;
 
/**
 * 加密拦截器 包含加密字段查询时 的加密步骤
 * 
 * @author cedoo
 * @since 2021-4-1 10:40:52
 */
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class),})
@ConditionalOnProperty(value = "domain.encrypt", havingValue = "true")
@Component
@Slf4j
public class ParammeterInterceptor implements Interceptor {
 
    @Autowired
    private IEncryptDecrypt encryptDecrypt;
 
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 拦截 ParameterHandler 的 setParameters 方法 动态设置参数
        if (invocation.getTarget() instanceof ParameterHandler) {
            ParameterHandler parameterHandler = (ParameterHandler)invocation.getTarget();
            PreparedStatement ps = (PreparedStatement)invocation.getArgs()[0];
 
            // 反射获取 参数对像
            Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject");
            parameterField.setAccessible(true);
            Object parameterObject = parameterField.get(parameterHandler);
            if (Objects.nonNull(parameterObject)) {
                Class<?> parameterObjectClass = parameterObject.getClass();
                EncryptDecryptClass encryptDecryptClass =
                    AnnotationUtils.findAnnotation(parameterObjectClass, EncryptDecryptClass.class);
                if (Objects.nonNull(encryptDecryptClass)) {
                    Field[] declaredFields = parameterObjectClass.getDeclaredFields();
                    final Object encrypt = encryptDecrypt.encrypt(declaredFields, parameterObject);
                }
                /**
                 * 通过加密字段查询时, 将查询参数中的加密字段加密后查询
                 */
                if (parameterObjectClass == MapperMethod.ParamMap.class) {
                    MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap)parameterObject;
                    boolean encrypted = false;
                    try {
                        /**
                         * 分页插件,会在分页查询时 进行多次查询,需要判断是否已对加密参数加密,防止多次加密后,查询失败
                         */
                        encrypted = paramMap.get("encrypted") != null;
                    } catch (BindingException be) {
                        encrypted = false;
                    }
                    if (!encrypted) {
                        Iterator iterator = paramMap.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, Object> entry = (Map.Entry<String, Object>)iterator.next();
                            if (entry.getKey().startsWith("param")) {
                                Object v = entry.getValue();
                                if (v != null) {
                                    EncryptQueryClass encryptQueryClass =
                                        AnnotationUtils.findAnnotation(v.getClass(), EncryptQueryClass.class);
                                    if (Objects.nonNull(encryptQueryClass)) {
                                        Field[] declaredFields = v.getClass().getDeclaredFields();
                                        for (Field field : declaredFields) {
                                            if (field.isAnnotationPresent(EncryptQuery.class)) {
                                                try {
                                                    final Object encrypt =
                                                        encryptDecrypt.encrypt(new Field[] {field}, v);
                                                    paramMap.put("encrypted", true);
                                                } catch (IllegalAccessException e) {
                                                    e.printStackTrace();
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
 
                }
 
            }
        }
        return invocation.proceed();
    }
 
    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o, this);
    }
 
    @Override
    public void setProperties(Properties properties) {
 
    }
}