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) {
|
|
}
|
}
|