From 4437989842e2d2a307b9ac82a27ae16f46499f98 Mon Sep 17 00:00:00 2001 From: weiweiw <14335254+weiweiw22@user.noreply.gitee.com> Date: Wed, 6 Nov 2024 08:45:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7=E9=82=AE?= =?UTF-8?q?=E7=AE=B1=E5=92=8C=E6=89=8B=E6=9C=BA=E5=8F=B7=E7=A0=81=E5=8A=A0?= =?UTF-8?q?=E5=AF=86=E5=AD=98=E5=82=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bonus/system/api/domain/SysUser.java | 4 +- .../bonus/system/config/MyBatisConfig.java | 20 +++ .../interceptor/DataEnDecryptInterceptor.java | 135 ++++++++++++++++++ .../resources/mapper/system/SysUserMapper.xml | 2 +- 4 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 bonus-modules/bonus-system/src/main/java/com/bonus/system/config/MyBatisConfig.java create mode 100644 bonus-modules/bonus-system/src/main/java/com/bonus/system/interceptor/DataEnDecryptInterceptor.java diff --git a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysUser.java b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysUser.java index d246146..f7cdca6 100644 --- a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysUser.java +++ b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/SysUser.java @@ -198,7 +198,7 @@ public class SysUser extends BaseEntity { } @Email(message = "邮箱格式不正确") - @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") +// @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") public String getEmail() { return email; } @@ -207,7 +207,7 @@ public class SysUser extends BaseEntity { this.email = email; } - @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") +// @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") public String getPhonenumber() { return phonenumber; } diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/config/MyBatisConfig.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/config/MyBatisConfig.java new file mode 100644 index 0000000..07f5e68 --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/config/MyBatisConfig.java @@ -0,0 +1,20 @@ +package com.bonus.system.config; + +import com.bonus.system.interceptor.DataEnDecryptInterceptor; +import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mybatis 配置类 + * @author weiweiwang + */ +@Configuration +public class MyBatisConfig { + @Bean + public ConfigurationCustomizer configurationCustomizer() { + return configuration -> { + configuration.addInterceptor(new DataEnDecryptInterceptor()); + }; + } +} \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/interceptor/DataEnDecryptInterceptor.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/interceptor/DataEnDecryptInterceptor.java new file mode 100644 index 0000000..3324024 --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/interceptor/DataEnDecryptInterceptor.java @@ -0,0 +1,135 @@ +package com.bonus.system.interceptor; + +import com.bonus.common.core.utils.encryption.Sm4Utils; +import com.bonus.system.api.domain.SysUser; +import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.executor.resultset.ResultSetHandler; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.plugin.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.sql.Statement; +/** + * mybatis 拦截器 + * 对用户邮箱和电话号码进行加密存库,并从库里查询后解密 + * @author weiweiwang + */ +@Intercepts({ + @Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class}), + @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) +}) +public class DataEnDecryptInterceptor implements Interceptor { + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Override + public Object intercept(Invocation invocation) throws Throwable { + try { + if (invocation.getTarget() instanceof ParameterHandler) { + // Handle encryption before setting parameters + ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget(); + MappedStatement mappedStatement = getMappedStatement(parameterHandler); + PreparedStatement preparedStatement = (PreparedStatement) invocation.getArgs()[0]; + Object parameterObject = parameterHandler.getParameterObject(); + String sqlId = mappedStatement.getId(); + if (!sqlId.contains("com.bonus.system.mapper.SysUserMapper")) + return invocation.proceed(); + + encryptObject (parameterObject); + + } else if (invocation.getTarget() instanceof ResultSetHandler) { + // Handle decryption after result set is obtained + ResultSetHandler resultSetHandler = (ResultSetHandler) invocation.getTarget(); + + MappedStatement mappedStatement = getMappedStatement(resultSetHandler); + Object result = invocation.proceed(); + + String sqlId = mappedStatement.getId(); + if (!sqlId.contains("com.bonus.system.mapper.SysUserMapper")) + return result; + + decryObject (result); + return result; + } + + return invocation.proceed(); + } + catch (Exception e){ + logger.error("mybatis对敏感数据加解密拦截器异常报错,{}",e.getMessage ()); + return invocation.proceed(); + } + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + @Override + public void setProperties(Properties properties) { + } + + private void encryptObject(Object parameterObject){ + if (parameterObject instanceof SysUser) { + SysUser user = (SysUser) parameterObject; + // 加密敏感字段 + if (user.getEmail() != null) { + user.setEmail(Sm4Utils.encode(user.getEmail())); + } + if (user.getPhonenumber() != null) { + user.setPhonenumber(Sm4Utils.encode(user.getPhonenumber())); + } + } + } + + private void decryObject(Object result){ + try { + if (result instanceof ArrayList) { + List list = (List) result; + for (Object obj : list) { + if (obj instanceof SysUser) { + decryptUser ((SysUser) obj); + } + } + } else if (result instanceof SysUser) { + decryptUser ((SysUser) result); + } + } catch (Exception ingore) { + } + } + private void decryptUser(SysUser user) { + if (user.getEmail() != null) { + user.setEmail(Sm4Utils.decode(user.getEmail())); + } + if (user.getPhonenumber() != null) { + user.setPhonenumber(Sm4Utils.decode(user.getPhonenumber())); + } + } + + private MappedStatement getMappedStatement(ParameterHandler parameterHandler) { + try { + // Use reflection to access the private field `mappedStatement` (or appropriate field) + Field mappedStatementField = parameterHandler.getClass().getDeclaredField("mappedStatement"); + mappedStatementField.setAccessible(true); + return (MappedStatement) mappedStatementField.get(parameterHandler); + } catch (Exception e) { + throw new RuntimeException("Failed to get MappedStatement from ParameterHandler", e); + } + } + + + private MappedStatement getMappedStatement(ResultSetHandler resultSetHandler) { + try { + // Use reflection to access the private field `mappedStatement` (or appropriate field) + Field mappedStatementField = resultSetHandler.getClass().getDeclaredField("mappedStatement"); + mappedStatementField.setAccessible(true); + return (MappedStatement) mappedStatementField.get(resultSetHandler); + } catch (Exception e) { + throw new RuntimeException("Failed to get MappedStatement from ResultSetHandler", e); + } + } +} \ No newline at end of file diff --git a/bonus-modules/bonus-system/src/main/resources/mapper/system/SysUserMapper.xml b/bonus-modules/bonus-system/src/main/resources/mapper/system/SysUserMapper.xml index a85cd29..6962d4c 100644 --- a/bonus-modules/bonus-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/bonus-modules/bonus-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -90,7 +90,7 @@