Commit a6526151 authored by 李健华's avatar 李健华

合规加密改造

parent e2a3c11f
# Created by https://www.gitignore.io
### log ###
.log
*.log
### svn ###
.svn/
......
......@@ -416,6 +416,11 @@
<artifactId>xxl-job-core</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>security</artifactId>
<version>0.1.2</version>
</dependency>
</dependencies>
......
......@@ -64,6 +64,7 @@ public interface Constants {
* 登录账号/手机号参数名
*/
String PHONE_NO = "phoneNo";
String ENCRYPTED_PHONE_NO = "encryptedPhoneNo";
String ID_NO = "idNo";
String USER_ID = "userId";
String USER_NAME = "name";
......
package cn.quantgroup.xyqb.config;
import cn.quantgroup.security.AESEncryption;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 统一加解密配置
*
* @author killer
* @date 2022年01月04日
* @see <a href="http://confluence.quantgroup.cn/pages/viewpage.action?pageId=61679207">confluence</a>
**/
@Configuration
public class SecurityConfig {
@Value("${keystone.security.key}")
private String key;
@Value("${keystone.security.iv}")
private String iv;
@Bean
public AESEncryption encryption() {
return new AESEncryption(key, iv, true);
}
}
package cn.quantgroup.xyqb.controller.external;
import cn.quantgroup.security.AESEncryption;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.accessable.IpValidator;
import cn.quantgroup.xyqb.aspect.captcha.CaptchaFiniteValidator;
......@@ -16,6 +17,7 @@ import cn.quantgroup.xyqb.exception.VerificationCodeErrorException;
import cn.quantgroup.xyqb.model.*;
import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.model.session.SessionValue;
import cn.quantgroup.xyqb.repository.IUserRepository;
import cn.quantgroup.xyqb.service.http.IHttpService;
import cn.quantgroup.xyqb.service.merchant.IMerchantService;
import cn.quantgroup.xyqb.service.register.IUserRegisterService;
......@@ -24,10 +26,7 @@ import cn.quantgroup.xyqb.service.sms.ISmsService;
import cn.quantgroup.xyqb.service.user.*;
import cn.quantgroup.xyqb.service.wechat.IWechatService;
import cn.quantgroup.xyqb.session.XyqbSessionContextHolder;
import cn.quantgroup.xyqb.util.IpUtil;
import cn.quantgroup.xyqb.util.PasswordUtil;
import cn.quantgroup.xyqb.util.TenantUtil;
import cn.quantgroup.xyqb.util.ValidationUtil;
import cn.quantgroup.xyqb.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
......@@ -725,7 +724,7 @@ public class UserController implements IBaseController {
}
LoginProperties loginProperties = new LoginProperties("", 4, channelId, createdFrom, appChannel, merchant.getId(), merchant.getName(), null);
//尝试解锁
lockIpv4Service.unLockPhone(user.getPhoneNo());
lockIpv4Service.unLockPhone(user.getEncryptedPhoneNo());
//更新session
return new JsonResult(sessionService.createSession(user, loginProperties));
}
......@@ -749,7 +748,7 @@ public class UserController implements IBaseController {
return false;
}
Long userId = user.getId();
String phoneNo = user.getPhoneNo();
String phoneNo = user.getEncryptedPhoneNo();
try {
int rows = wechatService.relateUser(userId, phoneNo, request.getParameter(Constants.WECHAT_OPEN_ID));
return rows > 0;
......@@ -832,4 +831,20 @@ public class UserController implements IBaseController {
return JsonResult.buildSuccessResult("登出成功");
}
/**
*
*/
@RequestMapping(value = "/encrypted", method = RequestMethod.GET)
public JsonResult encrypted() {
List<User> userList = userService.findAll();
/* 加密 */
AESEncryption aesEncryption = ApplicationContextHolder.getBean(AESEncryption.class);
for (User user : userList) {
String phoneNo = user.getPhoneNo();
user.setEncryptedPhoneNo(phoneNo);
userService.saveUser(user);
}
return JsonResult.buildSuccessResult();
}
}
......@@ -3,6 +3,7 @@ package cn.quantgroup.xyqb.entity;
import cn.quantgroup.xyqb.entity.baseEntity.PartitionEntity;
import cn.quantgroup.xyqb.entity.converter.EncryptConverter;
import cn.quantgroup.xyqb.util.StringUtils;
import javax.persistence.*;
......@@ -69,6 +70,10 @@ public class ProductLoginEntity extends PartitionEntity implements Serializable
@Column(name = "EXTENSION_ACCOUNT_ID", nullable = true)
private Long extensionAccountId;
@Column(name = "encrypted_phone_no")
@Convert(converter = EncryptConverter.class)
private String encryptedPhoneNo;
public long getCustomerId() {
return customerId;
}
......@@ -94,7 +99,7 @@ public class ProductLoginEntity extends PartitionEntity implements Serializable
}
public String getPhoneNo() {
return phoneNo;
return this.getEncryptedPhoneNo();
}
public void setPhoneNo(String phoneNo) {
......@@ -198,4 +203,12 @@ public class ProductLoginEntity extends PartitionEntity implements Serializable
public void setBatchNo(Integer batchNo) {
this.batchNo = batchNo;
}
public String getEncryptedPhoneNo() {
return encryptedPhoneNo == null ? phoneNo : encryptedPhoneNo;
}
public void setEncryptedPhoneNo(String encryptedPhoneNo) {
this.encryptedPhoneNo = encryptedPhoneNo;
}
}
package cn.quantgroup.xyqb.entity;
import cn.quantgroup.xyqb.entity.converter.EncryptConverter;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
......@@ -42,6 +40,18 @@ public class User extends BaseEntity implements Serializable {
@Column(name = "enable")
private Boolean enable;
@Column(name = "encrypted_phone_no")
@Convert(converter = EncryptConverter.class)
private String encryptedPhoneNo;
public String getEnctyptedPhoneNo() {
return encryptedPhoneNo == null ? phoneNo : encryptedPhoneNo;
}
public String getPhoneNo() {
return this.getEncryptedPhoneNo();
}
/**
* 是否有密码
*
......
package cn.quantgroup.xyqb.entity;
import cn.quantgroup.xyqb.entity.converter.EncryptConverter;
import cn.quantgroup.xyqb.util.EmojiUtil;
import lombok.Data;
import org.springframework.beans.BeanUtils;
......@@ -45,6 +46,10 @@ public class WechatUserInfo extends BaseEntity implements Serializable {
@Column(name = "utm_source")
private String utmSource;
@Column(name = "encrypted_phone_no")
@Convert(converter = EncryptConverter.class)
private String encryptedPhoneNo;
public WechatUserInfo convertEmoji() {
WechatUserInfo wechatUserInfo = new WechatUserInfo();
......
package cn.quantgroup.xyqb.entity.converter;
import cn.quantgroup.security.AESEncryption;
import cn.quantgroup.security.CipherUtil;
import cn.quantgroup.xyqb.util.ApplicationContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/**
* 通用字段加解密转换器
*
**/
@Slf4j
@Converter
public class EncryptConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String entityAttribute) {
if (StringUtils.isBlank(entityAttribute)) {
return entityAttribute;
}
/* 加密 */
AESEncryption aesEncryption = ApplicationContextHolder.getBean(AESEncryption.class);
return aesEncryption.encryptBase64(entityAttribute);
}
@Override
public String convertToEntityAttribute(String databaseColumn) {
if (StringUtils.isBlank(databaseColumn)) {
return databaseColumn;
}
/* 解密(兼容数据库字段未执行全部加密前的查询) */
AESEncryption aesEncryption = ApplicationContextHolder.getBean(AESEncryption.class);
if (CipherUtil.isCipherBase64(databaseColumn)) {
return aesEncryption.decryptBase64(databaseColumn);
}
return databaseColumn;
}
}
......@@ -34,6 +34,8 @@ public class UserRet implements Serializable {
//创建时间
private Long createdAt;
private String encryptedPhoneNo;
//上一次修改时间
private Long updatedAt;
......@@ -56,6 +58,7 @@ public class UserRet implements Serializable {
this.hasPassword = Objects.nonNull(user.getPassword()) && !Objects.equals("", user.getPassword());
this.setRegisteredFrom(user.getRegisteredFrom());
this.setUuid(user.getUuid());
this.setEncryptedPhoneNo(user.getEncryptedPhoneNo());
this.setCreatedAt(createTimeStamp);
this.setUpdatedAt(updateTimeStamp);
}
......
......@@ -15,6 +15,7 @@ public interface IProductLoginRepository extends JpaRepository<ProductLoginEntit
ProductLoginEntity findFirstByInstitutionIdAndProductIdAndPhoneNo(String institutionId, String productId, String phoneNo);
ProductLoginEntity findFirstByInstitutionIdAndProductIdAndEncryptedPhoneNo(String institutionId, String productId, String phoneNo);
ProductLoginEntity findFirstByPhoneNo(String phoneNo);
......
......@@ -17,6 +17,8 @@ public interface IUserRepository extends JpaRepository<User, Long>, JpaSpecifica
User findByPhoneNo(String phoneNo);
User findByEncryptedPhoneNo(String phoneNo);
User findByUuid(String uuid);
/**
......
......@@ -18,6 +18,8 @@ public interface IWeChatUserRepository extends JpaRepository<WechatUserInfo, Lon
WechatUserInfo findByPhoneNoAndAppName(String phoneNo, String appName);
WechatUserInfo findByEncryptedPhoneNoAndAppName(String phoneNo, String appName);
WechatUserInfo findByUserIdAndAppName(Long userId, String appName);
WechatUserInfo findFirstByUserIdAndAppNameOrderByCreatedAtDesc(Long userId, String appName);
......
......@@ -77,6 +77,7 @@ public class AppletServiceImpl implements IAppletService {
wechatUserInfo.setSex(appletParamEntry.getGender());
wechatUserInfo.setUnionId(appletParamEntry.getUnionId());
wechatUserInfo.setPhoneNo(appletParamEntry.getMobile());
wechatUserInfo.setEncryptedPhoneNo(appletParamEntry.getMobile());
wechatUserInfo.setUtmSource(appletParamEntry.getUtmSource());
if (null == wechatUserInfo.getUserId()) {//只要存在userid 就说明已经在用户表里了 不考虑小程序这边换手机号了
User user = userService.findByPhoneInDb(appletParamEntry.getMobile());
......
......@@ -136,6 +136,7 @@ public class UserRegisterServiceImpl implements IUserRegisterService {
user.setUuid(uuid);
user.setEnable(true);
user.setPhoneNo(userRegisterParam.getPhoneNo());
user.setEncryptedPhoneNo(userRegisterParam.getPhoneNo());
Long registerFrom = userRegisterParam.getRegisterFrom();
if (Objects.isNull(registerFrom)) {
registerFrom = 1L;
......
......@@ -107,6 +107,8 @@ public interface IUserService {
void kdspLogout(Long userId, LoginProperties loginProperties);
List<User> findAll();
/**
* 通过userId销户
*
......
......@@ -250,7 +250,8 @@ public class ModifyPhoneNoServiceImpl implements IModifyPhoneNoService {
if (userDetailRepository.findByUserIdAndPhoneNoAndNameAndIdNo(userId, prevPhoneNo, name, idCard) == null) {
throw new DataException("信息填写有误,请重新填写。");
}
if (userRepository.findByPhoneNo(curPhoneNo) != null) {
if (userService.findByPhoneInDb(curPhoneNo) != null) {
throw new DataException("填写信息有误,新手机号已注册。");
}
checkLoanStatus(userId);
......
......@@ -50,7 +50,7 @@ public class OauthLoginInfoServiceImpl implements IOauthLoginInfoService {
String phoneNo = user.getPhoneNo();
Long userId = user.getId();
ProductLoginEntity findProductLoginEntity = productLoginRepository.findByInstitutionIdAndProductIdAndExtensionAccountId(institutionId, productId, userId);
ProductLoginEntity findProductLoginByPhoneEntity = productLoginRepository.findFirstByInstitutionIdAndProductIdAndPhoneNo(institutionId, productId, phoneNo);
ProductLoginEntity findProductLoginByPhoneEntity = productLoginRepository.findFirstByInstitutionIdAndProductIdAndEncryptedPhoneNo(institutionId, productId, phoneNo);
log.info("=findProductLoginEntity -> {}", JSON.toJSONString(findProductLoginEntity));
log.info("=findProductLoginPhoneEntity -> {}", JSON.toJSONString(findProductLoginByPhoneEntity));
long uuid = 0L;
......@@ -66,6 +66,7 @@ public class OauthLoginInfoServiceImpl implements IOauthLoginInfoService {
Integer partitionKey = atomicSequencer.partitionKey(customerId);
ProductLoginEntity productLoginEntity = EntityBuilder.productLogin(productId, institutionId, phoneNo, customerId, customerName, partitionKey, id);
productLoginEntity.setExtensionAccountId(userId);
productLoginEntity.setEncryptedPhoneNo(phoneNo);
log.info("=addLoginInfo=save begin productLoginRepository={}", JSON.toJSONString(productLoginEntity));
productLoginRepository.save(productLoginEntity);
log.info("=addLoginInfo=save end productLoginRepository={}", JSON.toJSONString(productLoginEntity));
......@@ -118,7 +119,7 @@ public class OauthLoginInfoServiceImpl implements IOauthLoginInfoService {
String productId = oauthClientDetailsEntity.getProductId();
String phoneNo = user.getPhoneNo();
Long userId = user.getId();
ProductLoginEntity productLoginEntity = productLoginRepository.findFirstByInstitutionIdAndProductIdAndPhoneNo(institutionId, productId, phoneNo);
ProductLoginEntity productLoginEntity = productLoginRepository.findFirstByInstitutionIdAndProductIdAndEncryptedPhoneNo(institutionId, productId, phoneNo);
long uuid = 0L;
// 如果找不到该用户就创建
if ("".equals(productLoginEntity) || productLoginEntity == null) {
......@@ -131,6 +132,7 @@ public class OauthLoginInfoServiceImpl implements IOauthLoginInfoService {
Integer partitionKey = atomicSequencer.partitionKey(customerId);
productLoginEntity = EntityBuilder.productLogin(productId, institutionId, phoneNo, customerId, customerName, partitionKey, id);
productLoginEntity.setExtensionAccountId(userId);
productLoginEntity.setEncryptedPhoneNo(phoneNo);
log.info("=addRegisterInfo=save begin productLoginRepository= {}", JSON.toJSONString(productLoginEntity));
productLoginRepository.save(productLoginEntity);
log.info("=addRegisterInfo=save end productLoginRepository= {}", JSON.toJSONString(productLoginEntity));
......
......@@ -37,7 +37,7 @@ public class TenantServiceImpl implements ITenantService {
if (oauthClientDetails != null) {
ProductLoginEntity productLogin = productLoginService.findSlaveByPloginInfo(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), user.getId());
if (productLogin != null) {
if (!user.getPhoneNo().equals(productLogin.getPhoneNo())) {
if (!user.getEncryptedPhoneNo().equals(productLogin.getEncryptedPhoneNo())) {
return null;
}
user.setPassword(productLogin.getPassword());
......@@ -81,7 +81,7 @@ public class TenantServiceImpl implements ITenantService {
if (oauthClientDetails != null) {
ProductLoginEntity productLogin = productLoginService.findSlaveByPloginInfo(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), userDetail.getUserId());
if (productLogin != null) {
if (!userDetail.getPhoneNo().equals(productLogin.getPhoneNo())) {
if (!userDetail.getPhoneNo().equals(productLogin.getEncryptedPhoneNo())) {
return null;
}
......
......@@ -109,7 +109,11 @@ public class UserServiceImpl implements IUserService, IBaseController {
@Override
// @Cacheable(value = "usercache", key = "'xyqbuser' + #phone", unless = "#result == null", cacheManager = "cacheManager")
public User findByPhoneInDb(String phone) {
return userRepository.findByPhoneNo(phone);
User user = userRepository.findByEncryptedPhoneNo(phone);
if (user == null) {
user = userRepository.findByPhoneNo(phone);
}
return user;
}
@Override
......@@ -128,7 +132,7 @@ public class UserServiceImpl implements IUserService, IBaseController {
Map<Long, String> userIdAndPhoneMap = Maps.newHashMap();
List<User> users = userRepository.findByIdIn(userIds);
//校验租户ID
if (!tenantId.equals(tenantId)) {
if (!TenantUtil.TENANT_DEFAULT.equals(tenantId)) {
users = tenantService.selectUsersByTenantId(users, tenantId);
} else {
users = tenantService.validationTentIdByTentId(users, tenantId);
......@@ -168,16 +172,23 @@ public class UserServiceImpl implements IUserService, IBaseController {
@Override
public List<User> findByPhones(List<String> phones) {
return userRepository.findAll((root, query, cb) -> {
query.where(root.get(Constants.PHONE_NO).as(String.class).in(phones));
List<User> userList = userRepository.findAll((root, query, cb) -> {
query.where(root.get(Constants.ENCRYPTED_PHONE_NO).as(String.class).in(phones));
return query.getRestriction();
});
if (userList.isEmpty()) {
userList = userRepository.findAll((root, query, cb) -> {
query.where(root.get(Constants.PHONE_NO).as(String.class).in(phones));
return query.getRestriction();
});
}
return userList;
}
@Override
// @Cacheable(value = "usercache", key = "'xyqbuser' + #phone", unless = "#result == null", cacheManager = "cacheManager")
public User findByPhoneWithCache(String phone) {
return userRepository.findByPhoneNo(phone);
return userRepository.findByEncryptedPhoneNo(phone);
}
@Override
......@@ -202,7 +213,7 @@ public class UserServiceImpl implements IUserService, IBaseController {
@Override
@CacheEvict(value = "usercache", key = "'xyqbuser' + #phoneNo", cacheManager = "cacheManager")
public boolean resetPassword(String phoneNo, String password) {
User user = userRepository.findByPhoneNo(phoneNo);
User user = findByPhoneInDb(phoneNo);
if (user == null) {
throw new RuntimeException("用户[" + phoneNo + "]不存在");
}
......@@ -545,6 +556,11 @@ public class UserServiceImpl implements IUserService, IBaseController {
sessionService.kdspDeleteSession(userId, loginProperties);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Transactional(rollbackFor = Exception.class)
@Override
......
......@@ -197,7 +197,11 @@ public class WechatServiceImpl implements IWechatService {
if (!ValidationUtil.validatePhoneNo(phoneNo)) {
return null;
}
return weChatUserRepository.findByPhoneNoAndAppName(phoneNo, "xyqb");
WechatUserInfo userInfo = weChatUserRepository.findByEncryptedPhoneNoAndAppName(phoneNo, "xyqb");
if (userInfo == null) {
userInfo = weChatUserRepository.findByPhoneNoAndAppName(phoneNo, "xyqb");
}
return userInfo;
}
private String getTokenFromWechatServer(String code) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment