|
@@ -30,9 +30,6 @@ import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.context.annotation.Lazy;
|
|
import org.springframework.context.annotation.Lazy;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
-import org.springframework.web.context.request.RequestAttributes;
|
|
|
|
-import org.springframework.web.context.request.RequestContextHolder;
|
|
|
|
-import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
|
|
|
|
|
import javax.servlet.ServletRequest;
|
|
import javax.servlet.ServletRequest;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
@@ -56,7 +53,7 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
|
|
private final PerDpService perDpService;
|
|
private final PerDpService perDpService;
|
|
private final SystemService systemService;
|
|
private final SystemService systemService;
|
|
private final LoginRecordService loginRecordService;
|
|
private final LoginRecordService loginRecordService;
|
|
-// private final HttpServletRequest request;
|
|
|
|
|
|
+ private final HttpServletRequest request;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @param loginVO 登录参数类
|
|
* @param loginVO 登录参数类
|
|
@@ -64,10 +61,6 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
|
|
* @author 沈永艺
|
|
* @author 沈永艺
|
|
*/
|
|
*/
|
|
public String login(LoginVO loginVO) {
|
|
public String login(LoginVO loginVO) {
|
|
- RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
|
|
|
- ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
|
|
|
- HttpServletRequest httpRequest = sra.getRequest();
|
|
|
|
-
|
|
|
|
LoginRecordVO loginRecordVO = new LoginRecordVO();
|
|
LoginRecordVO loginRecordVO = new LoginRecordVO();
|
|
loginRecordVO.setLoginSystem(loginVO.getLoginSystem());
|
|
loginRecordVO.setLoginSystem(loginVO.getLoginSystem());
|
|
//获取已经存放进Redis的验证码 格式: verify-code:uuid(参数)
|
|
//获取已经存放进Redis的验证码 格式: verify-code:uuid(参数)
|
|
@@ -90,18 +83,8 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
|
|
//登录日志记录租户id
|
|
//登录日志记录租户id
|
|
loginRecordVO.setTenantId(personnel.getTenantId());
|
|
loginRecordVO.setTenantId(personnel.getTenantId());
|
|
//登录日志记录ip地址
|
|
//登录日志记录ip地址
|
|
- String ipAddress = httpRequest.getHeader("X-Forwarded-For");
|
|
|
|
- System.out.println(ipAddress);
|
|
|
|
- if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
|
|
|
- ipAddress = httpRequest.getHeader("X-Real-IP");
|
|
|
|
- System.out.println("未获得1"+ipAddress);
|
|
|
|
- }
|
|
|
|
- if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
|
|
|
- ipAddress = httpRequest.getRemoteAddr();
|
|
|
|
- System.out.println("未获得2"+ipAddress);
|
|
|
|
- }
|
|
|
|
- loginRecordVO.setLoginIp(ipAddress);
|
|
|
|
- String ua = httpRequest.getHeader("User-Agent");
|
|
|
|
|
|
+ loginRecordVO.setLoginIp(request.getRemoteAddr());
|
|
|
|
+ String ua = request.getHeader("User-Agent");
|
|
UserAgent userAgent = UserAgent.parseUserAgentString(ua);
|
|
UserAgent userAgent = UserAgent.parseUserAgentString(ua);
|
|
//获取客户端操作系统
|
|
//获取客户端操作系统
|
|
String os = userAgent.getOperatingSystem().getName();
|
|
String os = userAgent.getOperatingSystem().getName();
|
|
@@ -331,8 +314,198 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
|
|
map.put("value2", personnel.getPersonnelName());
|
|
map.put("value2", personnel.getPersonnelName());
|
|
mailUtils.sendEmailMessage(map);
|
|
mailUtils.sendEmailMessage(map);
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 登录加密
|
|
|
|
+ * @param vo
|
|
|
|
+ * @return
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
|
|
|
|
+ public String loginByEncryption(EncryptionLoginDTO vo) throws Exception {
|
|
|
|
+ final String username = vo.getUsername();
|
|
|
|
+ final String password = vo.getPassword();
|
|
|
|
+ String machineCode = vo.getMachineCode();
|
|
|
|
+ final String sign = vo.getSign();
|
|
|
|
+ final String appKey = vo.getAppKey();
|
|
|
|
+ long currentTimeMillis = vo.getCurrentTimeMillis() / 1000;
|
|
|
|
+ long currentTimeSecond = System.currentTimeMillis() / 1000;
|
|
|
|
+ final long second = currentTimeSecond - currentTimeMillis;
|
|
|
|
+ if (second > 30) {
|
|
|
|
+ return Response.error(ResponseEnum.THE_REQUEST_TIME_OVERTIME);
|
|
|
|
+ }
|
|
|
|
+ String appSecret = appKey + currentTimeMillis;
|
|
|
|
+ String md5Sign = SecureUtil.md5(appSecret);
|
|
|
|
+ if (Boolean.TRUE.equals(StringUtils.isEmpty(sign)) || !sign.equals(md5Sign)) {
|
|
|
|
+ return Response.error(ResponseEnum.THE_SIGN_IS_NOT_SAME);
|
|
|
|
+ }
|
|
|
|
+ if (Boolean.TRUE.equals(StringUtils.isEmpty(machineCode))) {
|
|
|
|
+ return Response.error(ResponseEnum.THE_MACHINE_CODE_IS_NULL);
|
|
|
|
+ }
|
|
|
|
+ //用用户名查询人员信息
|
|
|
|
+ LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ queryWrapper.eq(Personnel::getPersonnelUserName, username);
|
|
|
|
+ //获取一条
|
|
|
|
+ Personnel personnel = this.getOne(queryWrapper);
|
|
|
|
+ final Integer personId = personnel.getId();
|
|
|
|
+ //如果查不到 报错 用户名不存在
|
|
|
|
+ if (ObjectUtils.isEmpty(personnel)) {
|
|
|
|
+ return Response.error(ResponseEnum.USERNAME_ERROR);
|
|
|
|
+ }
|
|
|
|
+ //校验密码是否正确
|
|
|
|
+ boolean isPassword = personnel.getPersonnelPassword().equals(SecureUtil.md5(password));
|
|
|
|
+ if (!isPassword) {
|
|
|
|
+ //登录日志记录登录是否成功
|
|
|
|
+ return Response.error(ResponseEnum.PASSWORD_ERROR);
|
|
|
|
+ }
|
|
|
|
+ //人员信息中私钥或公钥为空则添加进去
|
|
|
|
+ updatePersonnel(personnel.getPrivateKey(), personnel.getPublicKey(), personnel.getSymmetryKey(), personId);
|
|
|
|
|
|
|
|
+ personnel = personnelMapper.selectById(personnel.getId());
|
|
|
|
+ List<AssoPersonnelMachine> machineList = assoPersonnelMachineMapper.selectList(new LambdaQueryWrapper<AssoPersonnelMachine>()
|
|
|
|
+ .eq(AssoPersonnelMachine::getPersonnelId, personId)
|
|
|
|
+ .ne(AssoPersonnelMachine::getMachineCode, SecureUtil.md5(machineCode)));
|
|
|
|
+ if (machineList.size() > 1) {
|
|
|
|
+ return Response.error(ResponseEnum.DO_NOT_LOG_IN_TO_MORE_THAN_TWO_NEW_MACHINES_WITH_THE_SAME_ACCOUNT);
|
|
|
|
+ }
|
|
|
|
+ boolean flag = addOrUpdatePersonnelMachine(machineCode, personnel);
|
|
|
|
+ EncryptionLoginVO loginVO = new EncryptionLoginVO();
|
|
|
|
+ if (flag) {
|
|
|
|
+ loginVO.setPrivateKey(personnel.getPrivateKey());
|
|
|
|
+ }
|
|
|
|
+ loginVO.setPersonId(personId);
|
|
|
|
+ loginVO.setPersonnelName(personnel.getPersonnelName());
|
|
|
|
+ loginVO.setPersonnelUserName(personnel.getPersonnelUserName());
|
|
|
|
+ loginVO.setPersonnelPhone(personnel.getPersonnelPhone());
|
|
|
|
+ loginVO.setMachineCode(vo.getMachineCode());
|
|
|
|
+ //Sa-token 登录方法 登录后 生成Token 如果集成了Redis的话 会自动存入Redis
|
|
|
|
+ StpUtil.login(personnel.getId());
|
|
|
|
+ loginVO.setToken(StpUtil.getTokenValue());
|
|
|
|
+ return Response.success(loginVO);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public void updatePersonnel(String privateKey, String publicKey, String symmetryKey, Integer personId) throws Exception {
|
|
|
|
+ if (StringUtils.isEmpty(privateKey) || StringUtils.isEmpty(publicKey) || Boolean.TRUE.equals(StringUtils.isEmpty(symmetryKey))) {
|
|
|
|
+ Map<String, String> map = RSAUtils.generateKey();
|
|
|
|
+ String publicKeyStr = map.get("publicKeyStr");
|
|
|
|
+ String privateKeyStr = map.get("privateKeyStr");
|
|
|
|
+ String generateKey = AESUtils.generateKey();
|
|
|
|
+ Personnel newPersonnel = personnelMapper.selectById(personId);
|
|
|
|
+ newPersonnel.setPrivateKey(privateKeyStr);
|
|
|
|
+ newPersonnel.setPublicKey(publicKeyStr);
|
|
|
|
+ newPersonnel.setSymmetryKey(generateKey);
|
|
|
|
+ newPersonnel.updateById();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 新增或修改人员机器码关联表
|
|
|
|
+ *
|
|
|
|
+ * @param machineCode
|
|
|
|
+ * @param personnel
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private boolean addOrUpdatePersonnelMachine(String machineCode, Personnel personnel) {
|
|
|
|
+ AssoPersonnelMachine machine = assoPersonnelMachineMapper.selectOne(new LambdaQueryWrapper<AssoPersonnelMachine>()
|
|
|
|
+ .eq(AssoPersonnelMachine::getMachineCode, SecureUtil.md5(machineCode))
|
|
|
|
+ .eq(AssoPersonnelMachine::getPersonnelId, personnel.getId()));
|
|
|
|
+ if (ObjectUtils.isEmpty(machine)) {
|
|
|
|
+ AssoPersonnelMachine assoPersonnelMachine = new AssoPersonnelMachine();
|
|
|
|
+ assoPersonnelMachine.setPersonnelId(personnel.getId());
|
|
|
|
+ assoPersonnelMachine.setMachineCode(SecureUtil.md5(machineCode));
|
|
|
|
+ assoPersonnelMachine.setIfFirstActivation(true);
|
|
|
|
+ assoPersonnelMachine.setCreateUser(personnel.getCreateUser());
|
|
|
|
+ assoPersonnelMachine.setCreateTime(new Date());
|
|
|
|
+ assoPersonnelMachine.insert();
|
|
|
|
+ return true;
|
|
|
|
+ } else {
|
|
|
|
+ machine.setId(machine.getId());
|
|
|
|
+ machine.setIfFirstActivation(false);
|
|
|
|
+ machine.updateById();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 功能模块化代码加密
|
|
|
|
+ * @param vo
|
|
|
|
+ * @return
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public String functionByEncryption(EncryptionFunctionDTO vo) throws Exception {
|
|
|
|
+ String sign = vo.getSign();
|
|
|
|
+ String appKey = vo.getAppKey();
|
|
|
|
+ long currentTimeMillis = vo.getCurrentTimeMillis() / 1000;
|
|
|
|
+ long currentTimeSecond = System.currentTimeMillis() / 1000;
|
|
|
|
+ long second = currentTimeSecond - currentTimeMillis;
|
|
|
|
+ if (second > 30) {
|
|
|
|
+ return Response.error(ResponseEnum.THE_REQUEST_TIME_OVERTIME);
|
|
|
|
+ }
|
|
|
|
+ String appSecret = appKey + currentTimeMillis;
|
|
|
|
+ String md5Sign = SecureUtil.md5(appSecret);
|
|
|
|
+ if (Boolean.TRUE.equals(StringUtils.isEmpty(sign)) || !sign.equals(md5Sign)) {
|
|
|
|
+ return Response.error(ResponseEnum.THE_SIGN_IS_NOT_SAME);
|
|
|
|
+ }
|
|
|
|
+ Integer userId = StpUtil.getLoginIdAsInt();
|
|
|
|
+ Personnel personnel = this.getById(userId);
|
|
|
|
+ if (ObjectUtils.isEmpty(personnel)) {
|
|
|
|
+ return Response.error(ResponseEnum.THE_TOKEN_IS_INVALID);
|
|
|
|
+ }
|
|
|
|
+ String publicKey = personnel.getPublicKey();
|
|
|
|
+ String symmetryKey = personnel.getSymmetryKey();
|
|
|
|
+ EncryptionFunctionFinalVO finalVO = new EncryptionFunctionFinalVO();
|
|
|
|
+ List<EncryptionFunctionVO> functionVOS = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ List<String> permissions = new ArrayList<>();
|
|
|
|
+ //1.获取该人员角色下权限id
|
|
|
|
+ List<Integer> functionIds = roleFunctionDataService.getPermission(StpUtil.getLoginIdAsInt());
|
|
|
|
+ if (!CollectionUtils.isEmpty(functionIds)) {
|
|
|
|
+ //2.用IDList在功能表中查出对应功能信息
|
|
|
|
+ List<Function> functionList = functionService.listByIds(functionIds);
|
|
|
|
+ //3.获取该人员角色所有权限
|
|
|
|
+ functionList.forEach(i -> {
|
|
|
|
+ permissions.add(i.getFunctionPath());
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ List<EncryptionFunctionVO> list = this.loadFunctionVOS(permissions, 2, symmetryKey);
|
|
|
|
+ functionVOS.addAll(list);
|
|
|
|
+
|
|
|
|
+ List<String> permissions1 = new ArrayList<>();
|
|
|
|
+ //获取所有权限
|
|
|
|
+ List<Function> functionList1 = functionService.list();
|
|
|
|
+
|
|
|
|
+ functionList1.forEach(i -> {
|
|
|
|
+ permissions1.add(i.getFunctionPath());
|
|
|
|
+ });
|
|
|
|
+ permissions1.removeAll(permissions);
|
|
|
|
+ List<EncryptionFunctionVO> list1 = this.loadFunctionVOS(permissions1, 1, symmetryKey);
|
|
|
|
+ functionVOS.addAll(list1);
|
|
|
|
+ finalVO.setFunctionVOS(functionVOS);
|
|
|
|
+ String key = RSAUtils.encryptByPublicKey(symmetryKey, publicKey);
|
|
|
|
+ finalVO.setKey(key);
|
|
|
|
+ return Response.success(finalVO);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<EncryptionFunctionVO> loadFunctionVOS(List<String> permissions, Integer type, String symmetryKey) throws Exception {
|
|
|
|
+ List<EncryptionFunctionVO> functionVOS = new ArrayList<>();
|
|
|
|
+ List<Function> functions = functionMapper.selectList(new LambdaQueryWrapper<Function>()
|
|
|
|
+ .in(Function::getFunctionPath, permissions));
|
|
|
|
+ for (Function function : functions) {
|
|
|
|
+ Integer functionId = function.getId();
|
|
|
|
+ String functionPath = function.getFunctionPath();
|
|
|
|
+ AssoFunctionModule functionModule = assoFunctionModuleMapper.selectOne(new LambdaQueryWrapper<AssoFunctionModule>()
|
|
|
|
+ .eq(AssoFunctionModule::getFunctionId, functionId)
|
|
|
|
+ .eq(AssoFunctionModule::getAuthType, type));
|
|
|
|
+ if (ObjectUtils.isNotEmpty(functionModule) && StringUtils.isNotEmpty(functionModule.getCode())) {
|
|
|
|
+ String moduleCode = functionModule.getCode();
|
|
|
|
+ String encryptInfo = AESUtils.encrypt(moduleCode, symmetryKey);
|
|
|
|
+ EncryptionFunctionVO functionVO = new EncryptionFunctionVO();
|
|
|
|
+ functionVO.setPermission(functionPath);
|
|
|
|
+ functionVO.setEncryptionModuleCode(encryptInfo);
|
|
|
|
+ functionVOS.add(functionVO);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return functionVOS;
|
|
|
|
+ }
|
|
}
|
|
}
|