package com.dl.framework.encrypt; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.dl.common.annotation.EncryptField; import com.dl.common.encrypt.EncryptContext; import com.dl.common.enums.AlgorithmType; import com.dl.common.enums.EncodeType; import com.dl.common.utils.StringUtils; import com.dl.framework.config.properties.EncryptorProperties; import com.dl.framework.manager.EncryptorManager; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.*; import java.lang.reflect.Field; import java.sql.Statement; import java.util.*; /** * 出参解密拦截器 * * @author 老马 * @version 4.6.0 */ @Slf4j @Intercepts({@Signature( type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) }) @AllArgsConstructor public class MybatisDecryptInterceptor implements Interceptor { private final EncryptorManager encryptorManager; private final EncryptorProperties defaultProperties; @Override public Object intercept(Invocation invocation) throws Throwable { // 获取执行mysql执行结果 Object result = invocation.proceed(); if (result == null) { return null; } decryptHandler(result); return result; } /** * 解密对象 * * @param sourceObject 待加密对象 */ private void decryptHandler(Object sourceObject) { if (ObjectUtil.isNull(sourceObject)) { return; } if (sourceObject instanceof Map) { new HashSet<>(((Map) sourceObject).values()).forEach(this::decryptHandler); return; } if (sourceObject instanceof List) { List sourceList = (List) sourceObject; if(CollUtil.isEmpty(sourceList)) { return; } // 判断第一个元素是否含有注解。如果没有直接返回,提高效率 Object firstItem = sourceList.get(0); if (ObjectUtil.isNull(firstItem) || CollUtil.isEmpty(encryptorManager.getFieldCache(firstItem.getClass()))) { return; } ((List) sourceObject).forEach(this::decryptHandler); return; } Set fields = encryptorManager.getFieldCache(sourceObject.getClass()); try { for (Field field : fields) { field.set(sourceObject, this.decryptField(String.valueOf(field.get(sourceObject)), field)); } } catch (Exception e) { log.error("处理解密字段时出错", e); } } /** * 字段值进行加密。通过字段的批注注册新的加密算法 * * @param value 待加密的值 * @param field 待加密字段 * @return 加密后结果 */ private String decryptField(String value, Field field) { if (ObjectUtil.isNull(value)) { return null; } EncryptField encryptField = field.getAnnotation(EncryptField.class); EncryptContext encryptContext = new EncryptContext(); encryptContext.setAlgorithm(encryptField.algorithm() == AlgorithmType.DEFAULT ? defaultProperties.getAlgorithm() : encryptField.algorithm()); encryptContext.setEncode(encryptField.encode() == EncodeType.DEFAULT ? defaultProperties.getEncode() : encryptField.encode()); encryptContext.setPassword(StringUtils.isBlank(encryptField.password()) ? defaultProperties.getPassword() : encryptField.password()); encryptContext.setPrivateKey(StringUtils.isBlank(encryptField.privateKey()) ? defaultProperties.getPrivateKey() : encryptField.privateKey()); encryptContext.setPublicKey(StringUtils.isBlank(encryptField.publicKey()) ? defaultProperties.getPublicKey() : encryptField.publicKey()); return this.encryptorManager.decrypt(value, encryptContext); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } }