增加用户邮箱和手机号码加密存储功能

This commit is contained in:
weiweiw 2024-11-06 08:45:37 +08:00
parent 9475184b9a
commit 4437989842
4 changed files with 158 additions and 3 deletions

View File

@ -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;
}

View File

@ -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());
};
}
}

View File

@ -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);
}
}
}

View File

@ -90,7 +90,7 @@
</sql>
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, INSERT(u.phonenumber,4,4,'****') as phonenumber,u.sex, u.status,
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber,u.sex, u.status,
u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.approval_status,u.is_permanent, d.dept_name,
d.leader from sys_user
u