ludc
2024-12-04 e405b861b9521f5ea38c5402203a5b05988f9de2
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/OsLoginServiceImpl.java
ÎļþÃû´Ó Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/LoginServiceImpl.java ÐÞ¸Ä
@@ -1,21 +1,17 @@
package com.vci.web.service.impl;
import com.vci.bo.LoginResultBO;
import com.vci.constant.CacheNameConstant;
import com.vci.corba.common.PLException;
import com.vci.corba.framework.data.DeptInfo;
import com.vci.corba.framework.data.LoginResult;
import com.vci.corba.framework.data.LoginState;
import com.vci.corba.framework.data.MachineInfo;
import com.vci.frameworkcore.ajaxTask.SmUserUnLockTask;
import com.vci.frameworkcore.ajaxTask.SmUserUnLockTaskManager;
import com.vci.frameworkcore.compatibility.ISmFunctionQueryService;
import com.vci.frameworkcore.compatibility.SmPwdStrategyQueryServiceI;
import com.vci.frameworkcore.compatibility.SmUserQueryServiceI;
import com.vci.frameworkcore.enumpck.ResourceControlTypeEnum;
import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus;
import com.vci.dto.LoginUserDTO;
import com.vci.lcstatuspck.FrameworkDataLCStatus;
import com.vci.pagemodel.SmFunctionVO;
import com.vci.pagemodel.SmPasswordStrategyVO;
import com.vci.pagemodel.SmUserVO;
import com.vci.frameworkcore.properties.VciSecurityManageProperties;
import com.vci.starter.web.annotation.bus.VciLoginAfter;
import com.vci.starter.web.annotation.bus.VciLogoutBefore;
import com.vci.starter.web.annotation.bus.VciLogoutPlugin;
@@ -25,15 +21,21 @@
import com.vci.starter.web.pagemodel.RequestClientInfo;
import com.vci.starter.web.pagemodel.SessionInfo;
import com.vci.starter.web.pagemodel.TokenVO;
import com.vci.starter.web.util.*;
import com.vci.bo.LoginResultBO;
import com.vci.constant.CacheNameConstant;
import com.vci.dto.LoginUserDTO;
import com.vci.web.properties.WebProperties;
import com.vci.starter.web.redis.RedisService;
import com.vci.web.service.LoginServiceI;
import com.vci.web.util.Func;
import com.vci.starter.web.util.ApplicationContextProvider;
import com.vci.starter.web.util.Lcm.Func;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.util.VciDateUtil;
import com.vci.starter.web.util.WebThreadLocalUtil;
import com.vci.web.ajaxTask.SmUserUnLockTask;
import com.vci.web.ajaxTask.SmUserUnLockTaskManager;
import com.vci.web.enumpck.ResourceControlTypeEnum;
import com.vci.web.properties.VciSecurityManageProperties;
import com.vci.web.properties.WebProperties;
import com.vci.web.service.ISmFunctionQueryService;
import com.vci.web.service.OsLoginServiceI;
import com.vci.web.service.SmPwdStrategyQueryServiceI;
import com.vci.web.service.SmUserQueryServiceI;
import com.vci.web.util.PlatformClientUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -55,7 +57,7 @@
 * @date 2020/1/29
 */
@Service
public class LoginServiceImpl implements LoginServiceI {
public class OsLoginServiceImpl implements OsLoginServiceI {
    /**
     * æ—¥å¿—
@@ -286,223 +288,6 @@
        return loginResult;
    }
    /**
     * ç™»å½•_废弃方法,主要用来备份
     * @param userDTO ç”¨æˆ·çš„æ•°æ®ä¼ è¾“对象
     * @param clientInfo å®¢æˆ·ç«¯çš„信息
     * @param checkPassword æ˜¯å¦æ ¡éªŒå¯†ç 
     * @return æ‰§è¡Œç»“æžœ
     * @throws VciBaseException å‚数错误,用户不能登录等会抛出异常
     */
    private LoginResultBO login_old(LoginUserDTO userDTO, RequestClientInfo clientInfo, boolean checkPassword/*单点登录不需要校验密码*/) throws VciBaseException, PLException {
        LoginResultBO loginResult = new LoginResultBO();
        loginResult.setSuccess(false);
        //1.判断用户的基本信息
        VciBaseUtil.alertNotNull(userDTO, "登录信息", userDTO.getUserId(), "用户账号");
        if (checkPassword) {
            VciBaseUtil.alertNotNull(userDTO.getPassword(), "登录密码");
        }
        //2、判断单设备登录,是否已经登录了
        String userIdTokenKey = CacheNameConstant.cacheKey(CacheNameConstant.USERID_TOKEN_KEY, userDTO.getUserId().trim());
        if(redisService.hasKey(userIdTokenKey) && !userDTO.isForceLogin() && securityManageProperties.isUserOneLogin()){
            loginResult.setFailCode(USER_IS_LOGINED);
            loginResult.setFailMsg("当前用户已经在其他地方登录!");
            return loginResult;
        }
        //说明已经登录了,那应该取消原来的登录
        if (redisService.hasKey(userIdTokenKey) && userDTO.isForceLogin() && securityManageProperties.isUserOneLogin()) {
            String tokenKey = redisService.getCacheObject(userIdTokenKey);
            redisService.deleteObject(tokenKey);
            redisService.deleteObject(userIdTokenKey);
        }
        //3.获取用户的对象(对象中包含角色部门还有密码策略信息)
        SmUserVO user = getUserByUserId(userDTO.getUserId().trim());
        if (user == null || StringUtils.isBlank(user.getOid())) {
            loginResult.setFailCode(USER_NOT_FOUND);
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
            return loginResult;
        }
        //3、判断密码是否正确
        if (checkPassword) {
            boolean passwordIsEqual = userQueryService.checkPasswordEqual(userDTO.getPassword(), user.getName());
            if (!passwordIsEqual) {
                if (logger.isDebugEnabled()) {
                    logger.debug("{}密码不正确", user.getId());
                }
            }
        }
        //4、调用平台登录接口,进行登录
        MachineInfo machine = getMachieInfo(clientInfo);
        machine.country = clientInfo.getCountry();
        machine.language = clientInfo.getLanguage();
        machine.osUser = clientInfo.getOsUser();
        machine.machine = clientInfo.getMachine();
        String token = null;
        try {
            LoginResult chkRes = platformClientUtil.getFrameworkService().checkLogin(userDTO.getUserId(),userDTO.getPassword(), machine);
            loginResult.setFailCode(getErrorCode(chkRes));
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId(), String.valueOf(chkRes.auxInfo)});
            if(chkRes.state == LoginState.Error || chkRes.state == LoginState.Locked || chkRes.state == LoginState.Freeze){
                return loginResult;
            }
            token = chkRes.token;
        } catch (Exception e) {
            loginResult.setFailCode(SYSTEM_ERROR);
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
            return loginResult;
        }
        if(StringUtils.isBlank(token)){
            loginResult.setFailMsg(TOKEN_EMPTY);
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
            return loginResult;
        }
        //如果用户已经被停用和锁定,不能登录
        if (FrameworkDataLCStatus.DISABLED.getValue().equals(user.getLcStatus())) {
            loginResult.setFailCode(USER_IS_DISABLED);
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
            return loginResult;
        }
        if (userQueryService.checkUserLock(user, user.getPwdWrongCount())) {
            loginResult.setFailCode(USER_IS_LOCK);
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
            return loginResult;
        }
        //如果用户的失效日期已经超过了当前时间,不能登录
        //只有新平台的用户才判断失效
        /*if (user.getDisabledate() != null) {
            //2021版本才有这个属性的值,当前这个没有这个值
            Date disableDate = VciDateUtil.addOrSubDate(user.getDisabledate(), Calendar.DATE, 1);
            if (disableDate != null && disableDate.getTime() < System.currentTimeMillis()) {
                loginResult.setFailCode(USER_MORE_THAN_DISABLE_DATE);
                loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
                return loginResult;
            }
        }*/
        //当前用户没有配置就查询默认的密码策略
        SmPasswordStrategyVO passwordStrategyVO = pwdStrategyQueryService.getPasswordStrategyVOByUserOid(user.getOid());
        if (checkPassword) {
            //前端需要先md5一次,然后后台再MD5一次,
            if (logger.isDebugEnabled()) {
                logger.debug("{}密码不正确", user.getId());
            }
            //只要数据没有问题就不存在密码策略为空的情况
            if (passwordStrategyVO == null) {
                //可能数据问题没有设置密码策略
                passwordStrategyVO = new SmPasswordStrategyVO();
                passwordStrategyVO.setRetryTime(6);
                passwordStrategyVO.setLockTime(30);
            }
            //判断密码错误次数是否达到上限
            if (passwordStrategyVO.getRetryTime() <= (user.getPwdWrongCount() + 1)) {
                user.setLockFlag(true);
                updateUserPwdWrongCount(user.getOid(), user.getPwdWrongCount() + 1);
                addUserToUnLock(userDTO.getUserId(), passwordStrategyVO.getLockTime());
                //updateUserPwdWrongCount(user.getOid(), user.getPwdWrongCount() + 1);
                loginResult.setFailCode(USER_PWD_LOCK);
                loginResult.setFailMsgArray(new String[]{userDTO.getUserId(), passwordStrategyVO.getLockTime() + ""});
                return loginResult;
            } else {
                //还没有到锁定的次数
                updateUserPwdWrongCount(user.getOid(), user.getPwdWrongCount() + 1);
                //5, è¿™æ˜¯ç¬¬ä¸€æ¬¡é”™è¯¯ï¼Œå‰©ä¸‹çš„æ˜¯ 5- ï¼ˆ0+1)
                loginResult.setFailCode(USER_PWD_NOT_EQUAL);
                loginResult.setFailMsgArray(new String[]{userDTO.getUserId(), (passwordStrategyVO.getRetryTime() - (user.getPwdWrongCount() + 1)) + ""});
                return loginResult;
            }
        }
        //检查是否该修改密码
        if (!clientInfo.isSso() && checkPassword) {
            //最后修改时间 + å¤±æ•ˆæ—¶é—´ï¼Œå¤§äºŽç­‰äºŽå½“前日期,则需要马上修改密码
            Date currentDay = null;
            try {
                currentDay = VciDateUtil.getNow(VciDateUtil.DateFormat);
            } catch (Throwable e) {
                if (logger.isErrorEnabled()) {
                    logger.error("获取当前日期", e);
                }
            }
            if (currentDay != null && passwordStrategyVO != null && passwordStrategyVO.getValidDay() != null) {
                Date inValidDay = null;
                if (user.getLastModifyPasswordTime() == null) {
                    //从来没有登录过
                    loginResult.setMustChangePassword(true);
                } else {
                    inValidDay = VciDateUtil.addOrSubDate(user.getLastModifyPasswordTime(), Calendar.DATE, passwordStrategyVO.getValidDay());
                    if (inValidDay.getTime() <= (currentDay).getTime()) {
                        loginResult.setMustChangePassword(true);
                    }
                }
                if (!loginResult.isMustChangePassword()) {
                    if (VciDateUtil.addOrSubDate(inValidDay, Calendar.DATE, -(passwordStrategyVO.getRemindDay())).getTime()
                            <= (currentDay).getTime()) {
                        //您的密码还有{0}天过期,请及时修改密码
                        long remainDay = VciDateUtil.getDaySub(inValidDay, currentDay);
                        loginResult.setPasswordInfo(MessageFormat.format(PASSWORD_REMAIN_DAY, new String[]{String.valueOf(remainDay)}));
                    }
                }
            }
        }
        //说明密码正确的
        if (logger.isDebugEnabled()) {
            logger.debug("{}的密码正确", user.getId());
        }
        user.setLastLoginTime(new Date());
        user.setPwdWrongCount(0);
        SessionInfo sessionInfo = new SessionInfo();
        sessionInfo.setToken(token);
        //初始化平台的token
        sessionForLogin.initInvocationInfo(sessionInfo);
        //拷贝用户的新到session会话中
        copyUser2SessionInfo(user, sessionInfo, userDTO.getLangCode());
        //拷贝请求信息到session会话中
        copyRequest2SessionInfo(clientInfo, sessionInfo);
        //获取人员所属的部门信息
        try {
            DeptInfo deptInfo = platformClientUtil.getFrameworkService().fetchDeptByUserId(user.getOid());
            sessionInfo.setDeptOid(deptInfo.id);
            sessionInfo.setDeptName(deptInfo.name);
            sessionInfo.setDeptNum(deptInfo.num);
        } catch (PLException e) {
            throw new VciBaseException("获取用户所属部门失败:"+e.getMessage());
        }
        /** //查询所有的角色
         List<SmRoleVO> roleVOList = roleQueryService.listRoleByUserOid(user.getOid(), null);
         if (!CollectionUtils.isEmpty(roleVOList)) {
         Map<String, String> roleOidNameMap = roleVOList.stream().collect(Collectors.toMap(s -> s.getOid(), t -> t.getName()));
         sessionInfo.setRolesName(roleOidNameMap);
         } else {
         sessionInfo.setRolesName(new HashMap());
         }
         //查询所有的权限
         List<SmFunctionVO> functionVOList = functionQueryService.listFunctionByUserOid(user.getOid(), null, ResourceControlTypeEnum.BS);
         if (!CollectionUtils.isEmpty(functionVOList)) {
         List<String> functionOidList = functionVOList.stream().map(s -> s.getOid()).collect(Collectors.toList());
         sessionInfo.setFunctionOids(functionOidList);
         } else {
         sessionInfo.setFunctionOids(new ArrayList());
         }*/
        //添加到会话信息
        TokenVO tokenVO = saveSessionInfo(sessionInfo);
        loginResult.setTokenVO(tokenVO);
        loginResult.setSuccess(true);
        return loginResult;
    }
    private MachineInfo getMachieInfo(RequestClientInfo clientInfo) {
        MachineInfo machine = new MachineInfo();
        machine.country = clientInfo.getCountry();
@@ -519,19 +304,6 @@
     */
    private SmUserVO getUserByUserId(String userId) {
        return userQueryService.getUserByUserId(userId);
    }
    /**
     * å•点登录
     *
     * @param userDTO    ç™»å½•信息
     * @param clientInfo è¯·æ±‚的客户端的信息
     * @return ç™»å½•的结果对象
     * @throws VciBaseException ç™»å½•失败的时候抛出异常
     */
    @Override
    public LoginResultBO singleLogin(LoginUserDTO userDTO, RequestClientInfo clientInfo) throws Exception {
        return login(userDTO,clientInfo,false);
    }
    /**