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 entry = (Map.Entry)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) { } }