From b0a2a8c927171795e3ed89a820caf829f76c80ee Mon Sep 17 00:00:00 2001 From: Charles7c Date: Tue, 13 Aug 2024 23:59:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(security/crypto):=20=E4=BF=AE=E5=A4=8D=20up?= =?UTF-8?q?dateById=20=E4=BF=AE=E6=94=B9=E6=9C=AA=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E5=8A=A0=E5=AF=86=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/AbstractMyBatisInterceptor.java | 154 +++++++++++------- .../core/MyBatisEncryptInterceptor.java | 6 +- 2 files changed, 96 insertions(+), 64 deletions(-) diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/AbstractMyBatisInterceptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/AbstractMyBatisInterceptor.java index 054bc0a1..d30100ba 100644 --- a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/AbstractMyBatisInterceptor.java +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/AbstractMyBatisInterceptor.java @@ -22,7 +22,9 @@ import cn.hutool.core.util.ReflectUtil; import cn.hutool.extra.spring.SpringUtil; import com.baomidou.mybatisplus.core.toolkit.Constants; import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.plugin.*; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.Interceptor; import top.continew.starter.core.constant.StringConstants; import top.continew.starter.core.exception.BusinessException; import top.continew.starter.security.crypto.annotation.FieldEncrypt; @@ -46,39 +48,6 @@ public abstract class AbstractMyBatisInterceptor implements Interceptor { private static final Map> ENCRYPT_PARAM_CACHE = new ConcurrentHashMap<>(); - /** - * 获取加密参数 - * - * @param mappedStatementId 映射语句 ID - * @return 加密参数 - */ - public Map getEncryptParams(String mappedStatementId) { - return getEncryptParams(mappedStatementId, null); - } - - /** - * 获取加密参数 - * - * @param mappedStatementId 映射语句 ID - * @param parameterIndex 参数索引 - * @return 加密参数 - */ - public Map getEncryptParams(String mappedStatementId, Integer parameterIndex) { - return ENCRYPT_PARAM_CACHE - .computeIfAbsent(mappedStatementId, key -> getEncryptParamsNoCached(mappedStatementId, parameterIndex)); - } - - /** - * 获取参数名称 - * - * @param parameter 参数 - * @return 参数名称 - */ - public String getParameterName(Parameter parameter) { - Param param = parameter.getAnnotation(Param.class); - return null != param ? param.value() : parameter.getName(); - } - /** * 获取所有字符串类型、需要加/解密的、有值字段 * @@ -114,13 +83,67 @@ public abstract class AbstractMyBatisInterceptor implements Interceptor { } /** - * 获取参数列表(无缓存) + * 获取加密参数 + * + * @param mappedStatement 映射语句 + * @return 加密参数 + */ + public Map getEncryptParams(MappedStatement mappedStatement) { + return getEncryptParams(mappedStatement, null); + } + + /** + * 获取加密参数 + * + * @param mappedStatement 映射语句 + * @param parameterCount 参数数量 + * @return 加密参数 + */ + public Map getEncryptParams(MappedStatement mappedStatement, Integer parameterCount) { + String mappedStatementId = mappedStatement.getId(); + SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); + if (SqlCommandType.UPDATE != sqlCommandType) { + return ENCRYPT_PARAM_CACHE.computeIfAbsent(mappedStatementId, key -> this + .getEncryptParams(mappedStatementId, parameterCount)); + } else { + return this.getEncryptParams(mappedStatementId, parameterCount); + } + } + + /** + * 获取参数名称 + * + * @param parameter 参数 + * @return 参数名称 + */ + public String getParameterName(Parameter parameter) { + Param param = parameter.getAnnotation(Param.class); + return null != param ? param.value() : parameter.getName(); + } + + /** + * 获取加密参数列表 * * @param mappedStatementId 映射语句 ID - * @param parameterIndex 参数数量 - * @return 参数列表 + * @param parameterCount 参数数量 + * @return 加密参数列表 */ - private Map getEncryptParamsNoCached(String mappedStatementId, Integer parameterIndex) { + private Map getEncryptParams(String mappedStatementId, Integer parameterCount) { + Method method = this.getMethod(mappedStatementId, parameterCount); + if (method == null) { + return Collections.emptyMap(); + } + return this.getEncryptParams(method); + } + + /** + * 获取映射方法 + * + * @param mappedStatementId 映射语句 ID + * @param parameterCount 参数数量 + * @return 映射方法 + */ + private Method getMethod(String mappedStatementId, Integer parameterCount) { try { String className = CharSequenceUtil.subBefore(mappedStatementId, StringConstants.DOT, true); String wrapperMethodName = CharSequenceUtil.subAfter(mappedStatementId, StringConstants.DOT, true); @@ -131,35 +154,42 @@ public abstract class AbstractMyBatisInterceptor implements Interceptor { .orElse(wrapperMethodName); // 获取真实方法 Optional methodOptional = Arrays.stream(ReflectUtil.getMethods(Class.forName(className), m -> { - if (Objects.nonNull(parameterIndex)) { - return Objects.equals(m.getName(), methodName) && m.getParameterCount() == parameterIndex; + if (parameterCount != null) { + return Objects.equals(m.getName(), methodName) && m.getParameterCount() == parameterCount; } return Objects.equals(m.getName(), methodName); })).findFirst(); - if (methodOptional.isEmpty()) { - return Collections.emptyMap(); - } - // 获取方法中的加密参数 - Map map = MapUtil.newHashMap(); - Parameter[] parameterArr = methodOptional.get().getParameters(); - for (int i = 0; i < parameterArr.length; i++) { - Parameter parameter = parameterArr[i]; - String parameterName = this.getParameterName(parameter); - FieldEncrypt fieldEncrypt = parameter.getAnnotation(FieldEncrypt.class); - if (null != fieldEncrypt) { - map.put(parameterName, fieldEncrypt); - if (String.class.equals(parameter.getType())) { - map.put("param" + (i + 1), fieldEncrypt); - } - } else if (parameterName.startsWith(Constants.ENTITY)) { - map.put(parameterName, null); - } else if (parameterName.startsWith(Constants.WRAPPER)) { - map.put(parameterName, null); - } - } - return map; + return methodOptional.orElse(null); } catch (ClassNotFoundException e) { throw new BusinessException(e.getMessage()); } } + + /** + * 获取加密参数列表 + * + * @param method 方法 + * @return 加密参数列表 + */ + private Map getEncryptParams(Method method) { + // 获取方法中的加密参数 + Map map = MapUtil.newHashMap(); + Parameter[] parameterArr = method.getParameters(); + for (int i = 0; i < parameterArr.length; i++) { + Parameter parameter = parameterArr[i]; + String parameterName = this.getParameterName(parameter); + FieldEncrypt fieldEncrypt = parameter.getAnnotation(FieldEncrypt.class); + if (null != fieldEncrypt) { + map.put(parameterName, fieldEncrypt); + if (String.class.equals(parameter.getType())) { + map.put("param" + (i + 1), fieldEncrypt); + } + } else if (parameterName.startsWith(Constants.ENTITY)) { + map.put(parameterName, null); + } else if (parameterName.startsWith(Constants.WRAPPER)) { + map.put(parameterName, null); + } + } + return map; + } } \ No newline at end of file diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/MyBatisEncryptInterceptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/MyBatisEncryptInterceptor.java index e5271047..88b7eac1 100644 --- a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/MyBatisEncryptInterceptor.java +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/continew/starter/security/crypto/core/MyBatisEncryptInterceptor.java @@ -109,8 +109,10 @@ public class MyBatisEncryptInterceptor extends AbstractMyBatisInterceptor { * @throws Exception / */ private void encryptMap(HashMap parameterMap, MappedStatement mappedStatement) throws Exception { - Map encryptParamMap = super.getEncryptParams(mappedStatement.getId(), parameterMap - .isEmpty() ? null : parameterMap.size() / 2); + Map encryptParamMap = super.getEncryptParams(mappedStatement); + if (encryptParamMap.isEmpty() && !parameterMap.isEmpty()) { + encryptParamMap = super.getEncryptParams(mappedStatement, parameterMap.size() / 2); + } for (Map.Entry encryptParamEntry : encryptParamMap.entrySet()) { String parameterName = encryptParamEntry.getKey(); if (parameterName.startsWith(Constants.ENTITY)) {