|
@@ -1,625 +1,625 @@
|
|
|
-package cn.com.qmth.examcloud.core.basic.service.impl;
|
|
|
-
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Set;
|
|
|
-
|
|
|
-import org.apache.commons.collections.CollectionUtils;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-
|
|
|
-import com.google.common.collect.Lists;
|
|
|
-import com.google.common.collect.Sets;
|
|
|
-
|
|
|
-import cn.com.qmth.examcloud.commons.base.exception.StatusException;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.ByteUtil;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.PropertiesUtil;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.SHA256;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.StringUtil;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.UUID;
|
|
|
-import cn.com.qmth.examcloud.commons.web.redis.RedisClient;
|
|
|
-import cn.com.qmth.examcloud.commons.web.security.bean.Role;
|
|
|
-import cn.com.qmth.examcloud.commons.web.security.bean.User;
|
|
|
-import cn.com.qmth.examcloud.commons.web.security.bean.UserType;
|
|
|
-import cn.com.qmth.examcloud.commons.web.security.enums.RoleMeta;
|
|
|
-import cn.com.qmth.examcloud.core.basic.base.constants.PropKeys;
|
|
|
-import cn.com.qmth.examcloud.core.basic.base.enums.AccountType;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.OrgRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.PrivilegeRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.RolePrivilegeRelationRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.RoleRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.StudentRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.ThirdPartyAccessRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.UserRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.UserRoleRelationRepo;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.OrgEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.PrivilegeEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.RoleEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.RolePrivilegeRelationEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.StudentEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.ThirdPartyAccessEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.ThirdPartyAccessPK;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.UserEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.dao.entity.UserRoleRelationEntity;
|
|
|
-import cn.com.qmth.examcloud.core.basic.service.AuthService;
|
|
|
-import cn.com.qmth.examcloud.core.basic.service.SmsCodeService;
|
|
|
-import cn.com.qmth.examcloud.core.basic.service.SysConfigService;
|
|
|
-import cn.com.qmth.examcloud.core.basic.service.UserService;
|
|
|
-import cn.com.qmth.examcloud.core.basic.service.bean.LoginInfo;
|
|
|
-
|
|
|
-/**
|
|
|
- * 类注释
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @date 2018年5月25日
|
|
|
- * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
- */
|
|
|
-@Service
|
|
|
-public class AuthServiceImpl implements AuthService {
|
|
|
-
|
|
|
- @Autowired
|
|
|
- RedisClient redisClient;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- UserService userService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- UserRepo userRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- OrgRepo orgRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- RoleRepo roleRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- StudentRepo studentRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- ThirdPartyAccessRepo thirdPartyAccessRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- UserRoleRelationRepo userRoleRelationRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- RolePrivilegeRelationRepo rolePrivilegeRelationRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- PrivilegeRepo privilegeRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- SysConfigService sysConfigService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- SmsCodeService smsCodeService;
|
|
|
-
|
|
|
- @Override
|
|
|
- public User login(LoginInfo loginInfo) {
|
|
|
-
|
|
|
- String accountType = loginInfo.getAccountType();
|
|
|
- String accountValue = loginInfo.getAccountValue();
|
|
|
- String password = loginInfo.getPassword();
|
|
|
- String clientIp = loginInfo.getClientIp();
|
|
|
- String smsCode = loginInfo.getSmsCode();
|
|
|
- String sessionId = loginInfo.getSessionId();
|
|
|
- String imgCode = loginInfo.getImgCode();
|
|
|
-
|
|
|
- if (StringUtils.isBlank(accountType)) {
|
|
|
- throw new StatusException("B-001201", "accountType is null");
|
|
|
- }
|
|
|
- if (StringUtils.isBlank(accountValue)) {
|
|
|
- throw new StatusException("B-001202", "accountValue is null");
|
|
|
- }
|
|
|
-
|
|
|
- AccountType accountTypeEnum = null;
|
|
|
- try {
|
|
|
- accountTypeEnum = AccountType.valueOf(accountType);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new StatusException("B-001204", "accountType is wrong");
|
|
|
- }
|
|
|
-
|
|
|
- // 系统级别登陆限制
|
|
|
- if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)
|
|
|
- || AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)
|
|
|
- || AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
- Boolean stuClientLoginLimit = (Boolean) sysConfigService.get("STU_CLIENT_LOGIN_LIMIT");
|
|
|
- if (stuClientLoginLimit) {
|
|
|
- throw new StatusException("B-001505", "系统维护中... ...");
|
|
|
- }
|
|
|
- } else if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
- Boolean commonLoginLimit = (Boolean) sysConfigService.get("COMMON_LOGIN_LIMIT");
|
|
|
- if (commonLoginLimit) {
|
|
|
- throw new StatusException("B-001506", "系统维护中... ...");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Integer errorTimes = getLoginErrorTimes(accountTypeEnum, accountValue, clientIp);
|
|
|
- if (StringUtils.isNotBlank(sessionId) && StringUtils.isNotBlank(imgCode)) {
|
|
|
- String rightImgCode = redisClient.get("$_IMG_" + sessionId, String.class);
|
|
|
- if (null == rightImgCode || !rightImgCode.equalsIgnoreCase(imgCode)) {
|
|
|
- throw new StatusException("B-002303", "验证码错误");
|
|
|
- }
|
|
|
- } else if (5 < errorTimes) {
|
|
|
- throw new StatusException("B-001205", "登陆失败次数已达到上限,请5分钟后重试");
|
|
|
- }
|
|
|
-
|
|
|
- StudentEntity student = null;
|
|
|
-
|
|
|
- if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)) {
|
|
|
- student = studentRepo.findBySecurityPhone(accountValue);
|
|
|
- if (null == student) {
|
|
|
- throw new StatusException("B-001110", "学生不存在");
|
|
|
- }
|
|
|
- loginInfo.setRootOrgId(student.getRootOrgId());
|
|
|
- }
|
|
|
-
|
|
|
- Long rootOrgId = loginInfo.getRootOrgId();
|
|
|
- OrgEntity rootOrg = null;
|
|
|
- if (null == rootOrgId) {
|
|
|
- if (StringUtils.isBlank(loginInfo.getDomain())) {
|
|
|
- throw new StatusException("B-001001", "domain,rootOrgId 必须有一个不为空");
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- rootOrg = orgRepo.findByParentIdIsNullAndDomainName(loginInfo.getDomain());
|
|
|
- rootOrgId = rootOrg.getId();
|
|
|
- } catch (Exception e) {
|
|
|
- throw new StatusException("B-001002", "机构不存在", e);
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
- rootOrg = orgRepo.findOne(Long.valueOf(rootOrgId));
|
|
|
- if (null == rootOrg) {
|
|
|
- throw new StatusException("B-001002", "机构不存在");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- String accessibleRootOrgIds = (String) sysConfigService.get("ACCESSIBLE_ROOT_ORG_LIST");
|
|
|
- if (StringUtils.isNotBlank(accessibleRootOrgIds)) {
|
|
|
- accessibleRootOrgIds = "," + accessibleRootOrgIds + ",";
|
|
|
- if (!accessibleRootOrgIds.contains("," + rootOrg.getId() + ",")) {
|
|
|
- throw new StatusException("B-001101", "系统维护中... ...");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- User user = new User();
|
|
|
- user.setRootOrgId(rootOrg.getId());
|
|
|
- user.setRootOrgName(rootOrg.getName());
|
|
|
- Long orgId = null;
|
|
|
-
|
|
|
- // 常规账户登录
|
|
|
- if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
- UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, accountValue);
|
|
|
- if (null == userEntity) {
|
|
|
- throw new StatusException("B-001004", "账号或密码错误");
|
|
|
- }
|
|
|
- if (null != userEntity.getEnable() && !userEntity.getEnable()) {
|
|
|
- throw new StatusException("B-001005", "账号被禁用");
|
|
|
- }
|
|
|
- if (StringUtils.isBlank(password)) {
|
|
|
- throw new StatusException("B-001203", "账号或密码错误");
|
|
|
- }
|
|
|
-
|
|
|
- user.setUserId(userEntity.getId());
|
|
|
- user.setUserType(UserType.COMMON);
|
|
|
- user.setDisplayName(userEntity.getLoginName() + " (" + userEntity.getName() + ")");
|
|
|
- orgId = userEntity.getOrgId();
|
|
|
-
|
|
|
- List<Role> roleList = getUserRoles(userEntity.getId());
|
|
|
- user.setRoleList(roleList);
|
|
|
-
|
|
|
- if (isSuperAdmin(user)) {
|
|
|
- byte[] bytes = SHA256.encode(userEntity.getLoginName() + password);
|
|
|
- String encodePassword = ByteUtil.toHexAscii(bytes);
|
|
|
- if (!encodePassword.equals(userEntity.getPassword())) {
|
|
|
- whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
- throw new StatusException("B-001003", "账号或密码错误");
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (!password.equals(userEntity.getPassword())) {
|
|
|
- whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
- throw new StatusException("B-001003", "账号或密码错误");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
- // 学生学号登录
|
|
|
- if (AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
- student = studentRepo.findByStudentCodeAndRootOrgId(accountValue, rootOrg.getId());
|
|
|
- }
|
|
|
- // 学生身份证号登录
|
|
|
- else if (AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)) {
|
|
|
- student = studentRepo.findByIdentityNumberAndRootOrgId(accountValue,
|
|
|
- rootOrg.getId());
|
|
|
- }
|
|
|
-
|
|
|
- if (null == student) {
|
|
|
- throw new StatusException("B-001110", "账号或密码错误");
|
|
|
- }
|
|
|
- if (null != student.getEnable() && !student.getEnable()) {
|
|
|
- throw new StatusException("B-001005", "账户被禁用");
|
|
|
- }
|
|
|
-
|
|
|
- // 验证码登录
|
|
|
- if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)
|
|
|
- && StringUtils.isNotBlank(smsCode)) {
|
|
|
- try {
|
|
|
- smsCodeService.checkSmsCode(accountValue, smsCode);
|
|
|
- } catch (Exception e) {
|
|
|
- whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
- throw e;
|
|
|
- }
|
|
|
- }
|
|
|
- // 密码登录
|
|
|
- else {
|
|
|
- if (StringUtils.isBlank(password)) {
|
|
|
- throw new StatusException("B-001203", "账号或密码错误");
|
|
|
- }
|
|
|
- String rightPassword = student.getPassword();
|
|
|
- if (!rightPassword.equals(password)) {
|
|
|
- whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
- throw new StatusException("B-001003", "账号或密码错误");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- user.setUserId(student.getId());
|
|
|
- user.setUserType(UserType.STUDENT);
|
|
|
- user.setDisplayName(student.getName());
|
|
|
- orgId = student.getOrgId();
|
|
|
-
|
|
|
- List<Role> roleList = Lists.newArrayList();
|
|
|
- user.setRoleList(roleList);
|
|
|
- }
|
|
|
-
|
|
|
- Boolean smsCodeEnable = PropertiesUtil.getBoolean("$login.admin.smsCode.enable", true);
|
|
|
- if (smsCodeEnable) {
|
|
|
- // 超级管理员短信验证
|
|
|
- if (isSuperAdmin(user)) {
|
|
|
- String phone = PropertiesUtil.getString("$login.admin.smsCode.phone");
|
|
|
- // 验证码不为空时,校验验证码
|
|
|
- if (StringUtils.isNotBlank(smsCode)) {
|
|
|
- try {
|
|
|
- smsCodeService.checkSmsCode(phone, smsCode);
|
|
|
- } catch (Exception e) {
|
|
|
- whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
- throw e;
|
|
|
- }
|
|
|
- }
|
|
|
- // 验证码为空时,发送验证码
|
|
|
- else {
|
|
|
- smsCodeService.sendSmsCode(phone);
|
|
|
- throw new StatusException("B-001100", "请输入短信验证码");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- user.setClientIp(loginInfo.getClientIp());
|
|
|
-
|
|
|
- OrgEntity org = null;
|
|
|
- if (null != orgId) {
|
|
|
- org = orgRepo.findOne(orgId);
|
|
|
- }
|
|
|
-
|
|
|
- boolean isLcUser = isLcUser(user);
|
|
|
-
|
|
|
- // 学习中心禁用时,学习中心用户禁止登录
|
|
|
- if (1 == user.getRoleList().size() && isLcUser) {
|
|
|
- if (null != org && !org.getEnable()) {
|
|
|
- throw new StatusException("B-001008", "学习中心被禁用");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- setSession(user);
|
|
|
- setRolePrivilegesCache(user);
|
|
|
-
|
|
|
- if (isLcUser) {
|
|
|
- setSecurityIp(user, orgId);
|
|
|
- }
|
|
|
-
|
|
|
- return user;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 登陆限制
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param accountType
|
|
|
- * @param accountValue
|
|
|
- * @param ip
|
|
|
- */
|
|
|
- private void whenLoginError(AccountType accountType, String accountValue, String ip) {
|
|
|
- String key = new StringBuilder("$_LOGIN_ERR_").append(accountType.getCode()).append("_")
|
|
|
- .append(accountValue).append("_").append(ip).toString();
|
|
|
-
|
|
|
- Integer times = redisClient.get(key, Integer.class);
|
|
|
- if (null != times) {
|
|
|
- times++;
|
|
|
- } else {
|
|
|
- times = 1;
|
|
|
- }
|
|
|
-
|
|
|
- redisClient.set(key, times, 300);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取登陆错误次数
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param accountType
|
|
|
- * @param accountValue
|
|
|
- * @param ip
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Integer getLoginErrorTimes(AccountType accountType, String accountValue, String ip) {
|
|
|
- String key = new StringBuilder("$_LOGIN_ERR_").append(accountType.getCode()).append("_")
|
|
|
- .append(accountValue).append("_").append(ip).toString();
|
|
|
-
|
|
|
- Integer times = redisClient.get(key, Integer.class);
|
|
|
-
|
|
|
- if (null == times) {
|
|
|
- times = 0;
|
|
|
- }
|
|
|
-
|
|
|
- return times;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置角色权限缓存
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param user
|
|
|
- */
|
|
|
- private void setRolePrivilegesCache(User user) {
|
|
|
-
|
|
|
- if (!user.getUserType().equals(UserType.COMMON)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- List<Role> roleList = user.getRoleList();
|
|
|
- Long rootOrgId = user.getRootOrgId();
|
|
|
- for (Role role : roleList) {
|
|
|
- Long roleId = role.getRoleId();
|
|
|
- List<RolePrivilegeRelationEntity> relationList = rolePrivilegeRelationRepo
|
|
|
- .findAllByRoleIdAndRootOrgId(roleId, rootOrgId);
|
|
|
-
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
- boolean first = true;
|
|
|
- for (RolePrivilegeRelationEntity cur : relationList) {
|
|
|
-
|
|
|
- PrivilegeEntity privilegeEntity = privilegeRepo.findOne(cur.getPrivilegeId());
|
|
|
- if (first) {
|
|
|
- sb.append(privilegeEntity.getCode());
|
|
|
- first = false;
|
|
|
- } else {
|
|
|
- sb.append(",").append(privilegeEntity.getCode());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- String key = "$_P_" + rootOrgId + "_" + roleId;
|
|
|
- redisClient.set(key, sb.toString());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置机构安全IP
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param user
|
|
|
- * @param orgId
|
|
|
- */
|
|
|
- private void setSecurityIp(User user, Long orgId) {
|
|
|
- if (null == orgId) {
|
|
|
- return;
|
|
|
- }
|
|
|
- String key = "IP_" + orgId;
|
|
|
-
|
|
|
- String clientIp = user.getClientIp();
|
|
|
- if (StringUtils.isBlank(clientIp)) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- String value = redisClient.get(key, String.class);
|
|
|
- Set<String> userKeySet = null;
|
|
|
- if (null == value) {
|
|
|
- userKeySet = Sets.newHashSet();
|
|
|
- } else {
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- Set<String> v = JsonUtil.fromJson(value, Set.class);
|
|
|
- userKeySet = v;
|
|
|
- }
|
|
|
-
|
|
|
- // 数据清洗
|
|
|
- Set<String> newUserKeySet = Sets.newHashSet();
|
|
|
- if (10 < userKeySet.size()) {
|
|
|
- for (String cur : userKeySet) {
|
|
|
- User curUser = redisClient.get(cur, User.class);
|
|
|
- if (null != curUser) {
|
|
|
- newUserKeySet.add(cur);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- newUserKeySet.add(user.getKey());
|
|
|
- redisClient.set(key, JsonUtil.toJson(newUserKeySet), 3600 * 12);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 是否是学习中心角色
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param user
|
|
|
- * @return
|
|
|
- */
|
|
|
- private boolean isLcUser(User user) {
|
|
|
- List<Role> roleList = user.getRoleList();
|
|
|
-
|
|
|
- for (Role role : roleList) {
|
|
|
- if (role.getRoleCode().equals(RoleMeta.LC_USER.name())) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- private boolean isSuperAdmin(User user) {
|
|
|
- List<Role> roleList = user.getRoleList();
|
|
|
-
|
|
|
- for (Role role : roleList) {
|
|
|
- if (role.getRoleCode().equals(RoleMeta.SUPER_ADMIN.name())) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 构建key
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param user
|
|
|
- * @return
|
|
|
- */
|
|
|
- private String buildUserKey(User user) {
|
|
|
- Long rootOrgId = user.getRootOrgId();
|
|
|
- UserType userType = user.getUserType();
|
|
|
- String key = StringUtil.join("U_", userType.getCode(), "_", rootOrgId, "_",
|
|
|
- user.getUserId());
|
|
|
- return key;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void logout(User user) {
|
|
|
- if (StringUtils.isNotBlank(user.getKey())) {
|
|
|
- redisClient.delete(user.getKey());
|
|
|
- } else {
|
|
|
- String key = buildUserKey(user);
|
|
|
- redisClient.delete(key);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public User getLoginUser(String key, String token) {
|
|
|
- int sessionTimeout = PropertiesUtil.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
- User user = redisClient.get(key, User.class, sessionTimeout);
|
|
|
- if (null == user) {
|
|
|
- throw new StatusException("B-001012", "未登录");
|
|
|
- }
|
|
|
-
|
|
|
- if (!user.getToken().equals(token)) {
|
|
|
- throw new StatusException("B-001012", "token错误");
|
|
|
- }
|
|
|
-
|
|
|
- return user;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public User thirdPartyAccess(Long rootOrgId, String loginName, String appId, String timestamp,
|
|
|
- String token, String clientIp) throws StatusException {
|
|
|
-
|
|
|
- OrgEntity rootOrg = orgRepo.findOne(rootOrgId);
|
|
|
- if (null == rootOrg) {
|
|
|
- throw new StatusException("B-001002", "机构不存在");
|
|
|
- }
|
|
|
-
|
|
|
- ThirdPartyAccessEntity thirdPartyAccess = thirdPartyAccessRepo
|
|
|
- .findOne(new ThirdPartyAccessPK(rootOrgId, appId));
|
|
|
-
|
|
|
- if (null == thirdPartyAccess) {
|
|
|
- throw new StatusException("B-001201", "第三方系统接入信息未配置");
|
|
|
- }
|
|
|
-
|
|
|
- long timestampLong = 0L;
|
|
|
- try {
|
|
|
- timestampLong = Long.parseLong(timestamp);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new StatusException("B-001202", "timestamp错误");
|
|
|
- }
|
|
|
-
|
|
|
- long currentTimeMillis = System.currentTimeMillis();
|
|
|
- if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccess.getTimeRange()) {
|
|
|
- throw new StatusException("B-001203", "timestamp超出时间差范围");
|
|
|
- }
|
|
|
-
|
|
|
- String secretKey = thirdPartyAccess.getSecretKey();
|
|
|
- String joinStr = StringUtil.join(loginName, rootOrgId, appId, timestamp, secretKey);
|
|
|
- byte[] bytes = SHA256.encode(joinStr);
|
|
|
- String hexAscii = ByteUtil.toHexAscii(bytes);
|
|
|
-
|
|
|
- if (!hexAscii.equalsIgnoreCase(token)) {
|
|
|
- throw new StatusException("B-001204", "token校验失败");
|
|
|
- }
|
|
|
-
|
|
|
- UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, loginName);
|
|
|
- if (userEntity == null) {
|
|
|
- throw new StatusException("B-001205", "用户不存在");
|
|
|
- }
|
|
|
-
|
|
|
- User user = new User();
|
|
|
- user.setUserType(UserType.COMMON);
|
|
|
- user.setUserId(userEntity.getId());
|
|
|
- user.setDisplayName(userEntity.getLoginName());
|
|
|
- user.setRootOrgId(userEntity.getRootOrgId());
|
|
|
-
|
|
|
- List<Role> roleList = getUserRoles(userEntity.getId());
|
|
|
- user.setRoleList(roleList);
|
|
|
-
|
|
|
- user.setClientIp(clientIp);
|
|
|
- setSession(user);
|
|
|
-
|
|
|
- boolean isLcUser = isLcUser(user);
|
|
|
-
|
|
|
- if (isLcUser) {
|
|
|
- setSecurityIp(user, userEntity.getOrgId());
|
|
|
- }
|
|
|
-
|
|
|
- return user;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置session
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param user
|
|
|
- */
|
|
|
- private void setSession(User user) {
|
|
|
- user.setTokenCreationTime(new Date());
|
|
|
- user.setToken(UUID.randomUUID());
|
|
|
- String key = buildUserKey(user);
|
|
|
- user.setKey(key);
|
|
|
-
|
|
|
- int sessionTimeout = PropertiesUtil.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
- Integer sessionTimeoutCache = redisClient.get("$_SESSION_TIMEOUT", Integer.class);
|
|
|
- if (null == sessionTimeoutCache || (int) sessionTimeoutCache != sessionTimeout) {
|
|
|
- redisClient.set("$_SESSION_TIMEOUT", sessionTimeout);
|
|
|
- }
|
|
|
-
|
|
|
- redisClient.set(key, user, sessionTimeout);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取角色集合
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param userId
|
|
|
- * @return
|
|
|
- */
|
|
|
- private List<Role> getUserRoles(Long userId) {
|
|
|
- List<UserRoleRelationEntity> relationList = userRoleRelationRepo.findAllByUserId(userId);
|
|
|
- List<Role> roleList = Lists.newArrayList();
|
|
|
- if (CollectionUtils.isNotEmpty(relationList)) {
|
|
|
- for (UserRoleRelationEntity cur : relationList) {
|
|
|
- Long roleId = cur.getRoleId();
|
|
|
- RoleEntity roleEntity = roleRepo.findOne(roleId);
|
|
|
- if (null == roleEntity) {
|
|
|
- throw new StatusException("B-002002", "roleId is wrong. roleId=" + roleId);
|
|
|
- }
|
|
|
- Role role = new Role(roleEntity.getId(), roleEntity.getCode(),
|
|
|
- roleEntity.getName());
|
|
|
- roleList.add(role);
|
|
|
- }
|
|
|
- }
|
|
|
- return roleList;
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
+package cn.com.qmth.examcloud.core.basic.service.impl;
|
|
|
+
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import com.google.common.collect.Sets;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
+import cn.com.qmth.examcloud.commons.util.ByteUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.util.JsonUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.util.PropertiesUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.util.SHA256;
|
|
|
+import cn.com.qmth.examcloud.commons.util.StringUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.util.UUID;
|
|
|
+import cn.com.qmth.examcloud.core.basic.base.constants.PropKeys;
|
|
|
+import cn.com.qmth.examcloud.core.basic.base.enums.AccountType;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.OrgRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.PrivilegeRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.RolePrivilegeRelationRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.RoleRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.StudentRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.ThirdPartyAccessRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.UserRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.UserRoleRelationRepo;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.OrgEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.PrivilegeEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.RoleEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.RolePrivilegeRelationEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.StudentEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.ThirdPartyAccessEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.ThirdPartyAccessPK;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.UserEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.UserRoleRelationEntity;
|
|
|
+import cn.com.qmth.examcloud.core.basic.service.AuthService;
|
|
|
+import cn.com.qmth.examcloud.core.basic.service.SmsCodeService;
|
|
|
+import cn.com.qmth.examcloud.core.basic.service.SysConfigService;
|
|
|
+import cn.com.qmth.examcloud.core.basic.service.UserService;
|
|
|
+import cn.com.qmth.examcloud.core.basic.service.bean.LoginInfo;
|
|
|
+import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
|
+import cn.com.qmth.examcloud.web.security.bean.Role;
|
|
|
+import cn.com.qmth.examcloud.web.security.bean.User;
|
|
|
+import cn.com.qmth.examcloud.web.security.bean.UserType;
|
|
|
+import cn.com.qmth.examcloud.web.security.enums.RoleMeta;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 类注释
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @date 2018年5月25日
|
|
|
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class AuthServiceImpl implements AuthService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ RedisClient redisClient;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ UserService userService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ UserRepo userRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ OrgRepo orgRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ RoleRepo roleRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ StudentRepo studentRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ ThirdPartyAccessRepo thirdPartyAccessRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ UserRoleRelationRepo userRoleRelationRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ RolePrivilegeRelationRepo rolePrivilegeRelationRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ PrivilegeRepo privilegeRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ SysConfigService sysConfigService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ SmsCodeService smsCodeService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public User login(LoginInfo loginInfo) {
|
|
|
+
|
|
|
+ String accountType = loginInfo.getAccountType();
|
|
|
+ String accountValue = loginInfo.getAccountValue();
|
|
|
+ String password = loginInfo.getPassword();
|
|
|
+ String clientIp = loginInfo.getClientIp();
|
|
|
+ String smsCode = loginInfo.getSmsCode();
|
|
|
+ String sessionId = loginInfo.getSessionId();
|
|
|
+ String imgCode = loginInfo.getImgCode();
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(accountType)) {
|
|
|
+ throw new StatusException("B-001201", "accountType is null");
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(accountValue)) {
|
|
|
+ throw new StatusException("B-001202", "accountValue is null");
|
|
|
+ }
|
|
|
+
|
|
|
+ AccountType accountTypeEnum = null;
|
|
|
+ try {
|
|
|
+ accountTypeEnum = AccountType.valueOf(accountType);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new StatusException("B-001204", "accountType is wrong");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 系统级别登陆限制
|
|
|
+ if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)
|
|
|
+ || AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)
|
|
|
+ || AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
+ Boolean stuClientLoginLimit = (Boolean) sysConfigService.get("STU_CLIENT_LOGIN_LIMIT");
|
|
|
+ if (stuClientLoginLimit) {
|
|
|
+ throw new StatusException("B-001505", "系统维护中... ...");
|
|
|
+ }
|
|
|
+ } else if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
+ Boolean commonLoginLimit = (Boolean) sysConfigService.get("COMMON_LOGIN_LIMIT");
|
|
|
+ if (commonLoginLimit) {
|
|
|
+ throw new StatusException("B-001506", "系统维护中... ...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer errorTimes = getLoginErrorTimes(accountTypeEnum, accountValue, clientIp);
|
|
|
+ if (StringUtils.isNotBlank(sessionId) && StringUtils.isNotBlank(imgCode)) {
|
|
|
+ String rightImgCode = redisClient.get("$_IMG_" + sessionId, String.class);
|
|
|
+ if (null == rightImgCode || !rightImgCode.equalsIgnoreCase(imgCode)) {
|
|
|
+ throw new StatusException("B-002303", "验证码错误");
|
|
|
+ }
|
|
|
+ } else if (5 < errorTimes) {
|
|
|
+ throw new StatusException("B-001205", "登陆失败次数已达到上限,请5分钟后重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ StudentEntity student = null;
|
|
|
+
|
|
|
+ if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)) {
|
|
|
+ student = studentRepo.findBySecurityPhone(accountValue);
|
|
|
+ if (null == student) {
|
|
|
+ throw new StatusException("B-001110", "学生不存在");
|
|
|
+ }
|
|
|
+ loginInfo.setRootOrgId(student.getRootOrgId());
|
|
|
+ }
|
|
|
+
|
|
|
+ Long rootOrgId = loginInfo.getRootOrgId();
|
|
|
+ OrgEntity rootOrg = null;
|
|
|
+ if (null == rootOrgId) {
|
|
|
+ if (StringUtils.isBlank(loginInfo.getDomain())) {
|
|
|
+ throw new StatusException("B-001001", "domain,rootOrgId 必须有一个不为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ rootOrg = orgRepo.findByParentIdIsNullAndDomainName(loginInfo.getDomain());
|
|
|
+ rootOrgId = rootOrg.getId();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new StatusException("B-001002", "机构不存在", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ rootOrg = orgRepo.findOne(Long.valueOf(rootOrgId));
|
|
|
+ if (null == rootOrg) {
|
|
|
+ throw new StatusException("B-001002", "机构不存在");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String accessibleRootOrgIds = (String) sysConfigService.get("ACCESSIBLE_ROOT_ORG_LIST");
|
|
|
+ if (StringUtils.isNotBlank(accessibleRootOrgIds)) {
|
|
|
+ accessibleRootOrgIds = "," + accessibleRootOrgIds + ",";
|
|
|
+ if (!accessibleRootOrgIds.contains("," + rootOrg.getId() + ",")) {
|
|
|
+ throw new StatusException("B-001101", "系统维护中... ...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ User user = new User();
|
|
|
+ user.setRootOrgId(rootOrg.getId());
|
|
|
+ user.setRootOrgName(rootOrg.getName());
|
|
|
+ Long orgId = null;
|
|
|
+
|
|
|
+ // 常规账户登录
|
|
|
+ if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
+ UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, accountValue);
|
|
|
+ if (null == userEntity) {
|
|
|
+ throw new StatusException("B-001004", "账号或密码错误");
|
|
|
+ }
|
|
|
+ if (null != userEntity.getEnable() && !userEntity.getEnable()) {
|
|
|
+ throw new StatusException("B-001005", "账号被禁用");
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(password)) {
|
|
|
+ throw new StatusException("B-001203", "账号或密码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ user.setUserId(userEntity.getId());
|
|
|
+ user.setUserType(UserType.COMMON);
|
|
|
+ user.setDisplayName(userEntity.getLoginName() + " (" + userEntity.getName() + ")");
|
|
|
+ orgId = userEntity.getOrgId();
|
|
|
+
|
|
|
+ List<Role> roleList = getUserRoles(userEntity.getId());
|
|
|
+ user.setRoleList(roleList);
|
|
|
+
|
|
|
+ if (isSuperAdmin(user)) {
|
|
|
+ byte[] bytes = SHA256.encode(userEntity.getLoginName() + password);
|
|
|
+ String encodePassword = ByteUtil.toHexAscii(bytes);
|
|
|
+ if (!encodePassword.equals(userEntity.getPassword())) {
|
|
|
+ whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
+ throw new StatusException("B-001003", "账号或密码错误");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!password.equals(userEntity.getPassword())) {
|
|
|
+ whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
+ throw new StatusException("B-001003", "账号或密码错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 学生学号登录
|
|
|
+ if (AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
+ student = studentRepo.findByStudentCodeAndRootOrgId(accountValue, rootOrg.getId());
|
|
|
+ }
|
|
|
+ // 学生身份证号登录
|
|
|
+ else if (AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)) {
|
|
|
+ student = studentRepo.findByIdentityNumberAndRootOrgId(accountValue,
|
|
|
+ rootOrg.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null == student) {
|
|
|
+ throw new StatusException("B-001110", "账号或密码错误");
|
|
|
+ }
|
|
|
+ if (null != student.getEnable() && !student.getEnable()) {
|
|
|
+ throw new StatusException("B-001005", "账户被禁用");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证码登录
|
|
|
+ if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)
|
|
|
+ && StringUtils.isNotBlank(smsCode)) {
|
|
|
+ try {
|
|
|
+ smsCodeService.checkSmsCode(accountValue, smsCode);
|
|
|
+ } catch (Exception e) {
|
|
|
+ whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 密码登录
|
|
|
+ else {
|
|
|
+ if (StringUtils.isBlank(password)) {
|
|
|
+ throw new StatusException("B-001203", "账号或密码错误");
|
|
|
+ }
|
|
|
+ String rightPassword = student.getPassword();
|
|
|
+ if (!rightPassword.equals(password)) {
|
|
|
+ whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
+ throw new StatusException("B-001003", "账号或密码错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ user.setUserId(student.getId());
|
|
|
+ user.setUserType(UserType.STUDENT);
|
|
|
+ user.setDisplayName(student.getName());
|
|
|
+ orgId = student.getOrgId();
|
|
|
+
|
|
|
+ List<Role> roleList = Lists.newArrayList();
|
|
|
+ user.setRoleList(roleList);
|
|
|
+ }
|
|
|
+
|
|
|
+ Boolean smsCodeEnable = PropertiesUtil.getBoolean("$login.admin.smsCode.enable", true);
|
|
|
+ if (smsCodeEnable) {
|
|
|
+ // 超级管理员短信验证
|
|
|
+ if (isSuperAdmin(user)) {
|
|
|
+ String phone = PropertiesUtil.getString("$login.admin.smsCode.phone");
|
|
|
+ // 验证码不为空时,校验验证码
|
|
|
+ if (StringUtils.isNotBlank(smsCode)) {
|
|
|
+ try {
|
|
|
+ smsCodeService.checkSmsCode(phone, smsCode);
|
|
|
+ } catch (Exception e) {
|
|
|
+ whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 验证码为空时,发送验证码
|
|
|
+ else {
|
|
|
+ smsCodeService.sendSmsCode(phone);
|
|
|
+ throw new StatusException("B-001100", "请输入短信验证码");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ user.setClientIp(loginInfo.getClientIp());
|
|
|
+
|
|
|
+ OrgEntity org = null;
|
|
|
+ if (null != orgId) {
|
|
|
+ org = orgRepo.findOne(orgId);
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean isLcUser = isLcUser(user);
|
|
|
+
|
|
|
+ // 学习中心禁用时,学习中心用户禁止登录
|
|
|
+ if (1 == user.getRoleList().size() && isLcUser) {
|
|
|
+ if (null != org && !org.getEnable()) {
|
|
|
+ throw new StatusException("B-001008", "学习中心被禁用");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ setSession(user);
|
|
|
+ setRolePrivilegesCache(user);
|
|
|
+
|
|
|
+ if (isLcUser) {
|
|
|
+ setSecurityIp(user, orgId);
|
|
|
+ }
|
|
|
+
|
|
|
+ return user;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 登陆限制
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param accountType
|
|
|
+ * @param accountValue
|
|
|
+ * @param ip
|
|
|
+ */
|
|
|
+ private void whenLoginError(AccountType accountType, String accountValue, String ip) {
|
|
|
+ String key = new StringBuilder("$_LOGIN_ERR_").append(accountType.getCode()).append("_")
|
|
|
+ .append(accountValue).append("_").append(ip).toString();
|
|
|
+
|
|
|
+ Integer times = redisClient.get(key, Integer.class);
|
|
|
+ if (null != times) {
|
|
|
+ times++;
|
|
|
+ } else {
|
|
|
+ times = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ redisClient.set(key, times, 300);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取登陆错误次数
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param accountType
|
|
|
+ * @param accountValue
|
|
|
+ * @param ip
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Integer getLoginErrorTimes(AccountType accountType, String accountValue, String ip) {
|
|
|
+ String key = new StringBuilder("$_LOGIN_ERR_").append(accountType.getCode()).append("_")
|
|
|
+ .append(accountValue).append("_").append(ip).toString();
|
|
|
+
|
|
|
+ Integer times = redisClient.get(key, Integer.class);
|
|
|
+
|
|
|
+ if (null == times) {
|
|
|
+ times = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return times;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置角色权限缓存
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param user
|
|
|
+ */
|
|
|
+ private void setRolePrivilegesCache(User user) {
|
|
|
+
|
|
|
+ if (!user.getUserType().equals(UserType.COMMON)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<Role> roleList = user.getRoleList();
|
|
|
+ Long rootOrgId = user.getRootOrgId();
|
|
|
+ for (Role role : roleList) {
|
|
|
+ Long roleId = role.getRoleId();
|
|
|
+ List<RolePrivilegeRelationEntity> relationList = rolePrivilegeRelationRepo
|
|
|
+ .findAllByRoleIdAndRootOrgId(roleId, rootOrgId);
|
|
|
+
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ boolean first = true;
|
|
|
+ for (RolePrivilegeRelationEntity cur : relationList) {
|
|
|
+
|
|
|
+ PrivilegeEntity privilegeEntity = privilegeRepo.findOne(cur.getPrivilegeId());
|
|
|
+ if (first) {
|
|
|
+ sb.append(privilegeEntity.getCode());
|
|
|
+ first = false;
|
|
|
+ } else {
|
|
|
+ sb.append(",").append(privilegeEntity.getCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String key = "$_P_" + rootOrgId + "_" + roleId;
|
|
|
+ redisClient.set(key, sb.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置机构安全IP
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param user
|
|
|
+ * @param orgId
|
|
|
+ */
|
|
|
+ private void setSecurityIp(User user, Long orgId) {
|
|
|
+ if (null == orgId) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String key = "IP_" + orgId;
|
|
|
+
|
|
|
+ String clientIp = user.getClientIp();
|
|
|
+ if (StringUtils.isBlank(clientIp)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String value = redisClient.get(key, String.class);
|
|
|
+ Set<String> userKeySet = null;
|
|
|
+ if (null == value) {
|
|
|
+ userKeySet = Sets.newHashSet();
|
|
|
+ } else {
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Set<String> v = JsonUtil.fromJson(value, Set.class);
|
|
|
+ userKeySet = v;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 数据清洗
|
|
|
+ Set<String> newUserKeySet = Sets.newHashSet();
|
|
|
+ if (10 < userKeySet.size()) {
|
|
|
+ for (String cur : userKeySet) {
|
|
|
+ User curUser = redisClient.get(cur, User.class);
|
|
|
+ if (null != curUser) {
|
|
|
+ newUserKeySet.add(cur);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ newUserKeySet.add(user.getKey());
|
|
|
+ redisClient.set(key, JsonUtil.toJson(newUserKeySet), 3600 * 12);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否是学习中心角色
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param user
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isLcUser(User user) {
|
|
|
+ List<Role> roleList = user.getRoleList();
|
|
|
+
|
|
|
+ for (Role role : roleList) {
|
|
|
+ if (role.getRoleCode().equals(RoleMeta.LC_USER.name())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isSuperAdmin(User user) {
|
|
|
+ List<Role> roleList = user.getRoleList();
|
|
|
+
|
|
|
+ for (Role role : roleList) {
|
|
|
+ if (role.getRoleCode().equals(RoleMeta.SUPER_ADMIN.name())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建key
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param user
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String buildUserKey(User user) {
|
|
|
+ Long rootOrgId = user.getRootOrgId();
|
|
|
+ UserType userType = user.getUserType();
|
|
|
+ String key = StringUtil.join("U_", userType.getCode(), "_", rootOrgId, "_",
|
|
|
+ user.getUserId());
|
|
|
+ return key;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void logout(User user) {
|
|
|
+ if (StringUtils.isNotBlank(user.getKey())) {
|
|
|
+ redisClient.delete(user.getKey());
|
|
|
+ } else {
|
|
|
+ String key = buildUserKey(user);
|
|
|
+ redisClient.delete(key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public User getLoginUser(String key, String token) {
|
|
|
+ int sessionTimeout = PropertiesUtil.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
+ User user = redisClient.get(key, User.class, sessionTimeout);
|
|
|
+ if (null == user) {
|
|
|
+ throw new StatusException("B-001012", "未登录");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!user.getToken().equals(token)) {
|
|
|
+ throw new StatusException("B-001012", "token错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ return user;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public User thirdPartyAccess(Long rootOrgId, String loginName, String appId, String timestamp,
|
|
|
+ String token, String clientIp) throws StatusException {
|
|
|
+
|
|
|
+ OrgEntity rootOrg = orgRepo.findOne(rootOrgId);
|
|
|
+ if (null == rootOrg) {
|
|
|
+ throw new StatusException("B-001002", "机构不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ ThirdPartyAccessEntity thirdPartyAccess = thirdPartyAccessRepo
|
|
|
+ .findOne(new ThirdPartyAccessPK(rootOrgId, appId));
|
|
|
+
|
|
|
+ if (null == thirdPartyAccess) {
|
|
|
+ throw new StatusException("B-001201", "第三方系统接入信息未配置");
|
|
|
+ }
|
|
|
+
|
|
|
+ long timestampLong = 0L;
|
|
|
+ try {
|
|
|
+ timestampLong = Long.parseLong(timestamp);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new StatusException("B-001202", "timestamp错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ long currentTimeMillis = System.currentTimeMillis();
|
|
|
+ if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccess.getTimeRange()) {
|
|
|
+ throw new StatusException("B-001203", "timestamp超出时间差范围");
|
|
|
+ }
|
|
|
+
|
|
|
+ String secretKey = thirdPartyAccess.getSecretKey();
|
|
|
+ String joinStr = StringUtil.join(loginName, rootOrgId, appId, timestamp, secretKey);
|
|
|
+ byte[] bytes = SHA256.encode(joinStr);
|
|
|
+ String hexAscii = ByteUtil.toHexAscii(bytes);
|
|
|
+
|
|
|
+ if (!hexAscii.equalsIgnoreCase(token)) {
|
|
|
+ throw new StatusException("B-001204", "token校验失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, loginName);
|
|
|
+ if (userEntity == null) {
|
|
|
+ throw new StatusException("B-001205", "用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ User user = new User();
|
|
|
+ user.setUserType(UserType.COMMON);
|
|
|
+ user.setUserId(userEntity.getId());
|
|
|
+ user.setDisplayName(userEntity.getLoginName());
|
|
|
+ user.setRootOrgId(userEntity.getRootOrgId());
|
|
|
+
|
|
|
+ List<Role> roleList = getUserRoles(userEntity.getId());
|
|
|
+ user.setRoleList(roleList);
|
|
|
+
|
|
|
+ user.setClientIp(clientIp);
|
|
|
+ setSession(user);
|
|
|
+
|
|
|
+ boolean isLcUser = isLcUser(user);
|
|
|
+
|
|
|
+ if (isLcUser) {
|
|
|
+ setSecurityIp(user, userEntity.getOrgId());
|
|
|
+ }
|
|
|
+
|
|
|
+ return user;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置session
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param user
|
|
|
+ */
|
|
|
+ private void setSession(User user) {
|
|
|
+ user.setTokenCreationTime(new Date());
|
|
|
+ user.setToken(UUID.randomUUID());
|
|
|
+ String key = buildUserKey(user);
|
|
|
+ user.setKey(key);
|
|
|
+
|
|
|
+ int sessionTimeout = PropertiesUtil.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
+ Integer sessionTimeoutCache = redisClient.get("$_SESSION_TIMEOUT", Integer.class);
|
|
|
+ if (null == sessionTimeoutCache || (int) sessionTimeoutCache != sessionTimeout) {
|
|
|
+ redisClient.set("$_SESSION_TIMEOUT", sessionTimeout);
|
|
|
+ }
|
|
|
+
|
|
|
+ redisClient.set(key, user, sessionTimeout);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取角色集合
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param userId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<Role> getUserRoles(Long userId) {
|
|
|
+ List<UserRoleRelationEntity> relationList = userRoleRelationRepo.findAllByUserId(userId);
|
|
|
+ List<Role> roleList = Lists.newArrayList();
|
|
|
+ if (CollectionUtils.isNotEmpty(relationList)) {
|
|
|
+ for (UserRoleRelationEntity cur : relationList) {
|
|
|
+ Long roleId = cur.getRoleId();
|
|
|
+ RoleEntity roleEntity = roleRepo.findOne(roleId);
|
|
|
+ if (null == roleEntity) {
|
|
|
+ throw new StatusException("B-002002", "roleId is wrong. roleId=" + roleId);
|
|
|
+ }
|
|
|
+ Role role = new Role(roleEntity.getId(), roleEntity.getCode(),
|
|
|
+ roleEntity.getName());
|
|
|
+ roleList.add(role);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return roleList;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|