|
@@ -1,48 +1,15 @@
|
|
|
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.api.commons.security.bean.Role;
|
|
|
import cn.com.qmth.examcloud.api.commons.security.bean.User;
|
|
|
import cn.com.qmth.examcloud.api.commons.security.bean.UserType;
|
|
|
import cn.com.qmth.examcloud.api.commons.security.enums.RoleMeta;
|
|
|
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.SHA256;
|
|
|
-import cn.com.qmth.examcloud.commons.util.StringUtil;
|
|
|
-import cn.com.qmth.examcloud.commons.util.UUID;
|
|
|
+import cn.com.qmth.examcloud.commons.util.*;
|
|
|
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.StudentCodeRepo;
|
|
|
-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.StudentCodeEntity;
|
|
|
-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.dao.*;
|
|
|
+import cn.com.qmth.examcloud.core.basic.dao.entity.*;
|
|
|
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.SystemPropertyService;
|
|
@@ -55,6 +22,16 @@ import cn.com.qmth.examcloud.support.cache.bean.StudentCacheBean;
|
|
|
import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
|
|
|
import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
|
|
|
import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import com.google.common.collect.Sets;
|
|
|
+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 java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Set;
|
|
|
|
|
|
/**
|
|
|
* {@link StatusException} 状态码范围:003XXX<br>
|
|
@@ -66,677 +43,676 @@ import cn.com.qmth.examcloud.web.redis.RedisClient;
|
|
|
@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
|
|
|
- StudentCodeRepo studentCodeRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- ThirdPartyAccessRepo thirdPartyAccessRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- UserRoleRelationRepo userRoleRelationRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- RolePrivilegeRelationRepo rolePrivilegeRelationRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- PrivilegeRepo privilegeRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- SystemPropertyService systemPropertyService;
|
|
|
-
|
|
|
- @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();
|
|
|
-
|
|
|
- if (StringUtils.isBlank(accountType)) {
|
|
|
- throw new StatusException("003201", "accountType is null");
|
|
|
- }
|
|
|
- if (StringUtils.isBlank(accountValue)) {
|
|
|
- throw new StatusException("003202", "accountValue is null");
|
|
|
- }
|
|
|
-
|
|
|
- AccountType accountTypeEnum = null;
|
|
|
- try {
|
|
|
- accountTypeEnum = AccountType.valueOf(accountType);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new StatusException("003204", "accountType is wrong");
|
|
|
- }
|
|
|
-
|
|
|
- // 系统级别登陆限制
|
|
|
- if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)
|
|
|
- || AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)
|
|
|
- || AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
- Boolean stuClientLoginLimit = (Boolean) systemPropertyService
|
|
|
- .get("STU_CLIENT_LOGIN_LIMIT");
|
|
|
- if (stuClientLoginLimit) {
|
|
|
- throw new StatusException("003505", "系统维护中... ...");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Integer errorTimes = getLoginErrorTimes(accountTypeEnum, accountValue, clientIp);
|
|
|
- if (5 < errorTimes) {
|
|
|
- throw new StatusException("003205", "登陆失败次数已达到上限,请5分钟后重试");
|
|
|
- }
|
|
|
-
|
|
|
- StudentEntity student = null;
|
|
|
-
|
|
|
- if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)) {
|
|
|
- student = studentRepo.findBySecurityPhone(accountValue);
|
|
|
- if (null == student) {
|
|
|
- throw new StatusException("003110", "学生不存在");
|
|
|
- }
|
|
|
- loginInfo.setRootOrgId(student.getRootOrgId());
|
|
|
- }
|
|
|
-
|
|
|
- Long rootOrgId = loginInfo.getRootOrgId();
|
|
|
- String domain = loginInfo.getDomain();
|
|
|
- String rootOrgName = null;
|
|
|
- Boolean rootOrgEnable = null;
|
|
|
-
|
|
|
- if (null == rootOrgId) {
|
|
|
- if (StringUtils.isBlank(domain)) {
|
|
|
- throw new StatusException("003003", "domain,rootOrgId 必须有一个不为空");
|
|
|
- }
|
|
|
- RootOrgCacheBean rootOrgCacheBean = CacheHelper.getRootOrg(domain);
|
|
|
- if (null == rootOrgCacheBean) {
|
|
|
- throw new StatusException("003003", "顶级机构不存在");
|
|
|
- }
|
|
|
- rootOrgId = rootOrgCacheBean.getId();
|
|
|
- rootOrgName = rootOrgCacheBean.getName();
|
|
|
- rootOrgEnable = rootOrgCacheBean.getEnable();
|
|
|
- } else {
|
|
|
- OrgCacheBean orgCacheBean = CacheHelper.getOrg(rootOrgId);
|
|
|
- if (null == orgCacheBean) {
|
|
|
- throw new StatusException("003003", "顶级机构不存在");
|
|
|
- }
|
|
|
- if (null != orgCacheBean.getParentId()) {
|
|
|
- throw new StatusException("003003", "顶级机构ID错误");
|
|
|
- }
|
|
|
-
|
|
|
- domain = orgCacheBean.getDomainName();
|
|
|
- rootOrgName = orgCacheBean.getName();
|
|
|
- rootOrgEnable = orgCacheBean.getEnable();
|
|
|
- }
|
|
|
-
|
|
|
- if (!rootOrgEnable) {
|
|
|
- throw new StatusException("003003", "顶级机构被禁用");
|
|
|
- }
|
|
|
-
|
|
|
- String accessibleRootOrgIds = (String) systemPropertyService
|
|
|
- .get("ACCESSIBLE_ROOT_ORG_LIST");
|
|
|
- if (StringUtils.isNotBlank(accessibleRootOrgIds)) {
|
|
|
- accessibleRootOrgIds = "," + accessibleRootOrgIds + ",";
|
|
|
- if (!accessibleRootOrgIds.contains("," + rootOrgId + ",")) {
|
|
|
- throw new StatusException("003101", "系统维护中... ...");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- User user = new User();
|
|
|
- user.setRootOrgId(rootOrgId);
|
|
|
- user.setRootOrgName(rootOrgName);
|
|
|
- user.setRootOrgDomain(domain);
|
|
|
- Long orgId = null;
|
|
|
-
|
|
|
- // 常规账户登录
|
|
|
- if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
- UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, accountValue);
|
|
|
- if (null == userEntity) {
|
|
|
- throw new StatusException("003004", "账号或密码错误");
|
|
|
- }
|
|
|
- if (null != userEntity.getEnable() && !userEntity.getEnable()) {
|
|
|
- throw new StatusException("003005", "账号被禁用");
|
|
|
- }
|
|
|
- if (StringUtils.isBlank(password)) {
|
|
|
- throw new StatusException("003203", "账号或密码错误");
|
|
|
- }
|
|
|
-
|
|
|
- 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("003003", "账号或密码错误");
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 系统级别登陆限制
|
|
|
- if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
- Boolean commonLoginLimit = (Boolean) systemPropertyService
|
|
|
- .get("COMMON_LOGIN_LIMIT");
|
|
|
- if (commonLoginLimit) {
|
|
|
- throw new StatusException("003506", "系统维护中... ...");
|
|
|
- }
|
|
|
- }
|
|
|
- if (!password.equals(userEntity.getPassword())) {
|
|
|
- whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
- throw new StatusException("003003", "账号或密码错误");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
- // 学生学号登录
|
|
|
- if (AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
- StudentCodeEntity scEntity = studentCodeRepo
|
|
|
- .findByStudentCodeAndRootOrgId(accountValue, rootOrgId);
|
|
|
- if (null == scEntity) {
|
|
|
- throw new StatusException("003009", "账号或密码错误");
|
|
|
- }
|
|
|
- student = GlobalHelper.getEntity(studentRepo, scEntity.getStudentId(),
|
|
|
- StudentEntity.class);
|
|
|
- }
|
|
|
- // 学生身份证号登录
|
|
|
- else if (AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)) {
|
|
|
- student = studentRepo.findByIdentityNumberAndRootOrgId(accountValue, rootOrgId);
|
|
|
- }
|
|
|
-
|
|
|
- if (null == student) {
|
|
|
- throw new StatusException("003110", "账号或密码错误");
|
|
|
- }
|
|
|
- if (null != student.getEnable() && !student.getEnable()) {
|
|
|
- throw new StatusException("003005", "账户被禁用");
|
|
|
- }
|
|
|
-
|
|
|
- // 验证码登录
|
|
|
- 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("003203", "账号或密码错误");
|
|
|
- }
|
|
|
- String rightPassword = student.getPassword();
|
|
|
- if (!rightPassword.equals(password)) {
|
|
|
- whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
- throw new StatusException("003003", "账号或密码错误");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- 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 = PropertyHolder.getBoolean("$login.admin.smsCode.enable", true);
|
|
|
- if (smsCodeEnable) {
|
|
|
- // 超级管理员短信验证
|
|
|
- if (isSuperAdmin(user)) {
|
|
|
- String phone = PropertyHolder.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("003100", "请输入短信验证码");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- user.setClientIp(loginInfo.getClientIp());
|
|
|
-
|
|
|
- OrgEntity org = null;
|
|
|
- if (null != orgId) {
|
|
|
- org = GlobalHelper.getEntity(orgRepo, orgId, OrgEntity.class);
|
|
|
- }
|
|
|
-
|
|
|
- boolean isLcUser = isLcUser(user);
|
|
|
-
|
|
|
- // 学习中心禁用时,学习中心用户禁止登录
|
|
|
- if (1 == user.getRoleList().size() && isLcUser) {
|
|
|
- if (null != org && !org.getEnable()) {
|
|
|
- throw new StatusException("003008", "学习中心被禁用");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Boolean noSession = loginInfo.getNoSession();
|
|
|
- if (null == noSession || !noSession) {
|
|
|
- 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 = GlobalHelper.getEntity(privilegeRepo,
|
|
|
- cur.getPrivilegeId(), PrivilegeEntity.class);
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void logout(User user) {
|
|
|
- if (StringUtils.isNotBlank(user.getKey())) {
|
|
|
- redisClient.delete(user.getKey());
|
|
|
- } else {
|
|
|
- String key = user.buildKey();
|
|
|
- redisClient.delete(key);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public User getLoginUser(String key, String token) {
|
|
|
- int sessionTimeout = PropertyHolder.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
- User user = redisClient.get(key, User.class, sessionTimeout);
|
|
|
- if (null == user) {
|
|
|
- throw new StatusException("003012", "未登录");
|
|
|
- }
|
|
|
-
|
|
|
- if (!user.getToken().equals(token)) {
|
|
|
- throw new StatusException("003012", "token错误");
|
|
|
- }
|
|
|
-
|
|
|
- return user;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public User thirdPartyCommonUserAccess(Long rootOrgId, String loginName, String appId,
|
|
|
- String timestamp, String token, String clientIp) throws StatusException {
|
|
|
-
|
|
|
- OrgEntity rootOrg = GlobalHelper.getEntity(orgRepo, rootOrgId, OrgEntity.class);
|
|
|
- if (null == rootOrg) {
|
|
|
- throw new StatusException("003003", "机构不存在");
|
|
|
- }
|
|
|
-
|
|
|
- ThirdPartyAccessEntity thirdPartyAccess = GlobalHelper.getEntity(thirdPartyAccessRepo,
|
|
|
- new ThirdPartyAccessPK(rootOrgId, appId), ThirdPartyAccessEntity.class);
|
|
|
-
|
|
|
- if (null == thirdPartyAccess) {
|
|
|
- throw new StatusException("003201", "第三方系统接入信息未配置");
|
|
|
- }
|
|
|
-
|
|
|
- long timestampLong = 0L;
|
|
|
- try {
|
|
|
- timestampLong = Long.parseLong(timestamp);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new StatusException("003202", "timestamp错误");
|
|
|
- }
|
|
|
-
|
|
|
- long currentTimeMillis = System.currentTimeMillis();
|
|
|
- if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccess.getTimeRange()) {
|
|
|
- throw new StatusException("003203", "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("003204", "token校验失败");
|
|
|
- }
|
|
|
-
|
|
|
- UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, loginName);
|
|
|
- if (userEntity == null) {
|
|
|
- throw new StatusException("003205", "用户不存在");
|
|
|
- }
|
|
|
-
|
|
|
- LoginInfo loginInfo = new LoginInfo();
|
|
|
- loginInfo.setAccountType(AccountType.COMMON_LOGIN_NAME.name());
|
|
|
- loginInfo.setAccountValue(loginName);
|
|
|
- loginInfo.setClientIp(clientIp);
|
|
|
- loginInfo.setRootOrgId(rootOrgId);
|
|
|
- loginInfo.setPassword(userEntity.getPassword());
|
|
|
-
|
|
|
- return login(loginInfo);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置session
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param user
|
|
|
- */
|
|
|
- private void setSession(User user) {
|
|
|
- user.setCreationTime(new Date());
|
|
|
- user.setToken(UUID.randomUUID());
|
|
|
- String key = user.buildKey();
|
|
|
- user.setKey(key);
|
|
|
-
|
|
|
- int sessionTimeout = PropertyHolder.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
- user.setSessionTimeout(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 = GlobalHelper.getEntity(roleRepo, roleId, RoleEntity.class);
|
|
|
- if (null == roleEntity) {
|
|
|
- throw new StatusException("003003", "roleId is wrong. roleId=" + roleId);
|
|
|
- }
|
|
|
- Role role = new Role(roleEntity.getId(), roleEntity.getCode(),
|
|
|
- roleEntity.getName());
|
|
|
- roleList.add(role);
|
|
|
- }
|
|
|
- }
|
|
|
- return roleList;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public User thirdPartyStudentAccess(Long rootOrgId, String accountType, String accountValue,
|
|
|
- String appId, String timestamp, String token, String clientIp) throws StatusException {
|
|
|
-
|
|
|
- OrgEntity rootOrg = GlobalHelper.getEntity(orgRepo, rootOrgId, OrgEntity.class);
|
|
|
- if (null == rootOrg) {
|
|
|
- throw new StatusException("003003", "机构不存在");
|
|
|
- }
|
|
|
-
|
|
|
- ThirdPartyAccessEntity thirdPartyAccess = GlobalHelper.getEntity(thirdPartyAccessRepo,
|
|
|
- new ThirdPartyAccessPK(rootOrgId, appId), ThirdPartyAccessEntity.class);
|
|
|
-
|
|
|
- if (null == thirdPartyAccess) {
|
|
|
- throw new StatusException("003201", "第三方系统接入信息未配置");
|
|
|
- }
|
|
|
-
|
|
|
- long timestampLong = 0L;
|
|
|
- try {
|
|
|
- timestampLong = Long.parseLong(timestamp);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new StatusException("003202", "timestamp错误");
|
|
|
- }
|
|
|
-
|
|
|
- long currentTimeMillis = System.currentTimeMillis();
|
|
|
- if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccess.getTimeRange()) {
|
|
|
- throw new StatusException("003203", "timestamp超出时间差范围");
|
|
|
- }
|
|
|
-
|
|
|
- String secretKey = thirdPartyAccess.getSecretKey();
|
|
|
- String joinStr = StringUtil.join(accountType, accountValue, rootOrgId, appId, timestamp,
|
|
|
- secretKey);
|
|
|
- byte[] bytes = SHA256.encode(joinStr);
|
|
|
- String hexAscii = ByteUtil.toHexAscii(bytes);
|
|
|
-
|
|
|
- if (!hexAscii.equalsIgnoreCase(token)) {
|
|
|
- throw new StatusException("003204", "token校验失败");
|
|
|
- }
|
|
|
-
|
|
|
- AccountType accountTypeEnum = null;
|
|
|
- try {
|
|
|
- accountTypeEnum = AccountType.valueOf(accountType);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new StatusException("003204", "accountType is wrong");
|
|
|
- }
|
|
|
-
|
|
|
- StudentEntity student = null;
|
|
|
-
|
|
|
- if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)) {
|
|
|
- student = studentRepo.findBySecurityPhone(accountValue);
|
|
|
- } else if (AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
- StudentCodeEntity scEntity = studentCodeRepo.findByStudentCodeAndRootOrgId(accountValue,
|
|
|
- rootOrg.getId());
|
|
|
- if (null != scEntity) {
|
|
|
- student = GlobalHelper.getEntity(studentRepo, scEntity.getStudentId(),
|
|
|
- StudentEntity.class);
|
|
|
- }
|
|
|
- }
|
|
|
- // 学生身份证号登录
|
|
|
- else if (AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)) {
|
|
|
- student = studentRepo.findByIdentityNumberAndRootOrgId(accountValue, rootOrg.getId());
|
|
|
- }
|
|
|
-
|
|
|
- if (null == student) {
|
|
|
- throw new StatusException("003110", "账号或密码错误");
|
|
|
- }
|
|
|
-
|
|
|
- LoginInfo loginInfo = new LoginInfo();
|
|
|
- loginInfo.setAccountType(AccountType.STUDENT_IDENTITY_NUMBER.name());
|
|
|
- loginInfo.setAccountValue(student.getIdentityNumber());
|
|
|
- loginInfo.setClientIp(clientIp);
|
|
|
- loginInfo.setRootOrgId(rootOrgId);
|
|
|
- loginInfo.setPassword(student.getPassword());
|
|
|
-
|
|
|
- return login(loginInfo);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public User login(UserType userType, Long userId) {
|
|
|
-
|
|
|
- User user = new User();
|
|
|
-
|
|
|
- Long rootOrgId = null;
|
|
|
-
|
|
|
- if (userType.equals(UserType.STUDENT)) {
|
|
|
-
|
|
|
- StudentCacheBean student = CacheHelper.getStudent(userId);
|
|
|
-
|
|
|
- user.setUserId(student.getId());
|
|
|
- user.setUserType(UserType.STUDENT);
|
|
|
- user.setDisplayName(student.getName());
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- UserEntity userEntity = GlobalHelper.getEntity(userRepo, userId, UserEntity.class);
|
|
|
- rootOrgId = userEntity.getRootOrgId();
|
|
|
-
|
|
|
- user.setUserId(userEntity.getId());
|
|
|
- user.setUserType(UserType.COMMON);
|
|
|
- user.setDisplayName(userEntity.getLoginName() + " (" + userEntity.getName() + ")");
|
|
|
-
|
|
|
- List<Role> roleList = getUserRoles(userEntity.getId());
|
|
|
- user.setRoleList(roleList);
|
|
|
- }
|
|
|
-
|
|
|
- user.setRootOrgId(rootOrgId);
|
|
|
- OrgCacheBean orgCacheBean = CacheHelper.getOrg(rootOrgId);
|
|
|
- user.setRootOrgName(orgCacheBean.getName());
|
|
|
- user.setRootOrgDomain(orgCacheBean.getDomainName());
|
|
|
-
|
|
|
- setSession(user);
|
|
|
-
|
|
|
- return user;
|
|
|
- }
|
|
|
+ @Autowired
|
|
|
+ RedisClient redisClient;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ UserService userService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ UserRepo userRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ OrgRepo orgRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ RoleRepo roleRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ StudentRepo studentRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ StudentCodeRepo studentCodeRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ ThirdPartyAccessRepo thirdPartyAccessRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ UserRoleRelationRepo userRoleRelationRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ RolePrivilegeRelationRepo rolePrivilegeRelationRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ PrivilegeRepo privilegeRepo;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ SystemPropertyService systemPropertyService;
|
|
|
+
|
|
|
+ @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();
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(accountType)) {
|
|
|
+ throw new StatusException("003201", "accountType is null");
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(accountValue)) {
|
|
|
+ throw new StatusException("003202", "accountValue is null");
|
|
|
+ }
|
|
|
+
|
|
|
+ AccountType accountTypeEnum = null;
|
|
|
+ try {
|
|
|
+ accountTypeEnum = AccountType.valueOf(accountType);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new StatusException("003204", "accountType is wrong");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 系统级别登陆限制
|
|
|
+ if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)
|
|
|
+ || AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)
|
|
|
+ || AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
+ Boolean stuClientLoginLimit = (Boolean) systemPropertyService
|
|
|
+ .get("STU_CLIENT_LOGIN_LIMIT");
|
|
|
+ if (stuClientLoginLimit) {
|
|
|
+ throw new StatusException("003505", "系统维护中... ...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer errorTimes = getLoginErrorTimes(accountTypeEnum, accountValue, clientIp);
|
|
|
+ if (5 < errorTimes) {
|
|
|
+ throw new StatusException("003205", "登陆失败次数已达到上限,请5分钟后重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ StudentEntity student = null;
|
|
|
+
|
|
|
+ if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)) {
|
|
|
+ student = studentRepo.findBySecurityPhone(accountValue);
|
|
|
+ if (null == student) {
|
|
|
+ throw new StatusException("003110", "学生不存在");
|
|
|
+ }
|
|
|
+ loginInfo.setRootOrgId(student.getRootOrgId());
|
|
|
+ }
|
|
|
+
|
|
|
+ Long rootOrgId = loginInfo.getRootOrgId();
|
|
|
+ String domain = loginInfo.getDomain();
|
|
|
+ String rootOrgName = null;
|
|
|
+ Boolean rootOrgEnable = null;
|
|
|
+
|
|
|
+ if (null == rootOrgId) {
|
|
|
+ if (StringUtils.isBlank(domain)) {
|
|
|
+ throw new StatusException("003003", "domain,rootOrgId 必须有一个不为空");
|
|
|
+ }
|
|
|
+ RootOrgCacheBean rootOrgCacheBean = CacheHelper.getRootOrg(domain);
|
|
|
+ if (null == rootOrgCacheBean) {
|
|
|
+ throw new StatusException("003003", "顶级机构不存在");
|
|
|
+ }
|
|
|
+ rootOrgId = rootOrgCacheBean.getId();
|
|
|
+ rootOrgName = rootOrgCacheBean.getName();
|
|
|
+ rootOrgEnable = rootOrgCacheBean.getEnable();
|
|
|
+ } else {
|
|
|
+ OrgCacheBean orgCacheBean = CacheHelper.getOrg(rootOrgId);
|
|
|
+ if (null == orgCacheBean) {
|
|
|
+ throw new StatusException("003003", "顶级机构不存在");
|
|
|
+ }
|
|
|
+ if (null != orgCacheBean.getParentId()) {
|
|
|
+ throw new StatusException("003003", "顶级机构ID错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ domain = orgCacheBean.getDomainName();
|
|
|
+ rootOrgName = orgCacheBean.getName();
|
|
|
+ rootOrgEnable = orgCacheBean.getEnable();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!rootOrgEnable) {
|
|
|
+ throw new StatusException("003003", "顶级机构被禁用");
|
|
|
+ }
|
|
|
+
|
|
|
+ String accessibleRootOrgIds = (String) systemPropertyService
|
|
|
+ .get("ACCESSIBLE_ROOT_ORG_LIST");
|
|
|
+ if (StringUtils.isNotBlank(accessibleRootOrgIds)) {
|
|
|
+ accessibleRootOrgIds = "," + accessibleRootOrgIds + ",";
|
|
|
+ if (!accessibleRootOrgIds.contains("," + rootOrgId + ",")) {
|
|
|
+ throw new StatusException("003101", "系统维护中... ...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ User user = new User();
|
|
|
+ user.setRootOrgId(rootOrgId);
|
|
|
+ user.setRootOrgName(rootOrgName);
|
|
|
+ user.setRootOrgDomain(domain);
|
|
|
+ Long orgId = null;
|
|
|
+
|
|
|
+ // 常规账户登录
|
|
|
+ if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
+ UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, accountValue);
|
|
|
+ if (null == userEntity) {
|
|
|
+ throw new StatusException("003004", "账号或密码错误");
|
|
|
+ }
|
|
|
+ if (null != userEntity.getEnable() && !userEntity.getEnable()) {
|
|
|
+ throw new StatusException("003005", "账号被禁用");
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(password)) {
|
|
|
+ throw new StatusException("003203", "账号或密码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ 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("003003", "账号或密码错误");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 系统级别登陆限制
|
|
|
+ if (AccountType.COMMON_LOGIN_NAME.equals(accountTypeEnum)) {
|
|
|
+ Boolean commonLoginLimit = (Boolean) systemPropertyService
|
|
|
+ .get("COMMON_LOGIN_LIMIT");
|
|
|
+ if (commonLoginLimit) {
|
|
|
+ throw new StatusException("003506", "系统维护中... ...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!password.equals(userEntity.getPassword())) {
|
|
|
+ whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
+ throw new StatusException("003003", "账号或密码错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 学生学号登录
|
|
|
+ if (AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
+ StudentCodeEntity scEntity = studentCodeRepo
|
|
|
+ .findByStudentCodeAndRootOrgId(accountValue, rootOrgId);
|
|
|
+ if (null == scEntity) {
|
|
|
+ throw new StatusException("003009", "账号或密码错误");
|
|
|
+ }
|
|
|
+ student = GlobalHelper.getEntity(studentRepo, scEntity.getStudentId(),
|
|
|
+ StudentEntity.class);
|
|
|
+ }
|
|
|
+ // 学生身份证号登录
|
|
|
+ else if (AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)) {
|
|
|
+ student = studentRepo.findByIdentityNumberAndRootOrgId(accountValue, rootOrgId);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null == student) {
|
|
|
+ throw new StatusException("003110", "账号或密码错误");
|
|
|
+ }
|
|
|
+ if (null != student.getEnable() && !student.getEnable()) {
|
|
|
+ throw new StatusException("003005", "账户被禁用");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证码登录
|
|
|
+ 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("003203", "账号或密码错误");
|
|
|
+ }
|
|
|
+ String rightPassword = student.getPassword();
|
|
|
+ if (!rightPassword.equals(password)) {
|
|
|
+ whenLoginError(accountTypeEnum, accountValue, clientIp);
|
|
|
+ throw new StatusException("003003", "账号或密码错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 = PropertyHolder.getBoolean("$login.admin.smsCode.enable", true);
|
|
|
+ if (smsCodeEnable) {
|
|
|
+ // 超级管理员短信验证
|
|
|
+ if (isSuperAdmin(user)) {
|
|
|
+ String phone = PropertyHolder.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("003100", "请输入短信验证码");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ user.setClientIp(loginInfo.getClientIp());
|
|
|
+
|
|
|
+ OrgEntity org = null;
|
|
|
+ if (null != orgId) {
|
|
|
+ org = GlobalHelper.getEntity(orgRepo, orgId, OrgEntity.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean isLcUser = isLcUser(user);
|
|
|
+
|
|
|
+ // 学习中心禁用时,学习中心用户禁止登录
|
|
|
+ if (1 == user.getRoleList().size() && isLcUser) {
|
|
|
+ if (null != org && !org.getEnable()) {
|
|
|
+ throw new StatusException("003008", "学习中心被禁用");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Boolean noSession = loginInfo.getNoSession();
|
|
|
+ if (null == noSession || !noSession) {
|
|
|
+ setSession(user);
|
|
|
+ }
|
|
|
+
|
|
|
+ setRolePrivilegesCache(user);
|
|
|
+
|
|
|
+ if (isLcUser) {
|
|
|
+ setSecurityIp(user, orgId);
|
|
|
+ }
|
|
|
+
|
|
|
+ return user;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 登陆限制
|
|
|
+ *
|
|
|
+ * @param accountType
|
|
|
+ * @param accountValue
|
|
|
+ * @param ip
|
|
|
+ * @author WANGWEI
|
|
|
+ */
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取登陆错误次数
|
|
|
+ *
|
|
|
+ * @param accountType
|
|
|
+ * @param accountValue
|
|
|
+ * @param ip
|
|
|
+ * @return
|
|
|
+ * @author WANGWEI
|
|
|
+ */
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置角色权限缓存
|
|
|
+ *
|
|
|
+ * @param user
|
|
|
+ * @author WANGWEI
|
|
|
+ */
|
|
|
+ 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 = GlobalHelper.getEntity(privilegeRepo,
|
|
|
+ cur.getPrivilegeId(), PrivilegeEntity.class);
|
|
|
+ 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
|
|
|
+ *
|
|
|
+ * @param user
|
|
|
+ * @param orgId
|
|
|
+ * @author WANGWEI
|
|
|
+ */
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否是学习中心角色
|
|
|
+ *
|
|
|
+ * @param user
|
|
|
+ * @return
|
|
|
+ * @author WANGWEI
|
|
|
+ */
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void logout(User user) {
|
|
|
+ if (StringUtils.isNotBlank(user.getKey())) {
|
|
|
+ redisClient.delete(user.getKey());
|
|
|
+ } else {
|
|
|
+ String key = user.buildKey();
|
|
|
+ redisClient.delete(key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public User getLoginUser(String key, String token) {
|
|
|
+ int sessionTimeout = PropertyHolder.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
+ User user = redisClient.get(key, User.class, sessionTimeout);
|
|
|
+ if (null == user) {
|
|
|
+ throw new StatusException("003012", "未登录");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!user.getToken().equals(token)) {
|
|
|
+ throw new StatusException("003012", "token错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ return user;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public User thirdPartyCommonUserAccess(Long rootOrgId, String loginName, String appId,
|
|
|
+ String timestamp, String token, String clientIp) throws StatusException {
|
|
|
+
|
|
|
+ OrgEntity rootOrg = GlobalHelper.getEntity(orgRepo, rootOrgId, OrgEntity.class);
|
|
|
+ if (null == rootOrg) {
|
|
|
+ throw new StatusException("003003", "机构不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ ThirdPartyAccessEntity thirdPartyAccess = GlobalHelper.getEntity(thirdPartyAccessRepo,
|
|
|
+ new ThirdPartyAccessPK(rootOrgId, appId), ThirdPartyAccessEntity.class);
|
|
|
+
|
|
|
+ if (null == thirdPartyAccess) {
|
|
|
+ throw new StatusException("003201", "第三方系统接入信息未配置");
|
|
|
+ }
|
|
|
+
|
|
|
+ long timestampLong = 0L;
|
|
|
+ try {
|
|
|
+ timestampLong = Long.parseLong(timestamp);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new StatusException("003202", "timestamp错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ long currentTimeMillis = System.currentTimeMillis();
|
|
|
+ if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccess.getTimeRange()) {
|
|
|
+ throw new StatusException("003203", "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("003204", "token校验失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ UserEntity userEntity = userRepo.findByRootOrgIdAndLoginName(rootOrgId, loginName);
|
|
|
+ if (userEntity == null) {
|
|
|
+ throw new StatusException("003205", "用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ LoginInfo loginInfo = new LoginInfo();
|
|
|
+ loginInfo.setAccountType(AccountType.COMMON_LOGIN_NAME.name());
|
|
|
+ loginInfo.setAccountValue(loginName);
|
|
|
+ loginInfo.setClientIp(clientIp);
|
|
|
+ loginInfo.setRootOrgId(rootOrgId);
|
|
|
+ loginInfo.setPassword(userEntity.getPassword());
|
|
|
+
|
|
|
+ return login(loginInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置session
|
|
|
+ *
|
|
|
+ * @param user
|
|
|
+ * @author WANGWEI
|
|
|
+ */
|
|
|
+ private void setSession(User user) {
|
|
|
+ user.setCreationTime(new Date());
|
|
|
+ user.setToken(UUID.randomUUID());
|
|
|
+ String key = user.buildKey();
|
|
|
+ user.setKey(key);
|
|
|
+
|
|
|
+ int sessionTimeout = PropertyHolder.getInt(PropKeys.SESSION_TIMEOUT, 3600);
|
|
|
+ user.setSessionTimeout(sessionTimeout);
|
|
|
+
|
|
|
+ redisClient.set(key, user, sessionTimeout);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取角色集合
|
|
|
+ *
|
|
|
+ * @param userId
|
|
|
+ * @return
|
|
|
+ * @author WANGWEI
|
|
|
+ */
|
|
|
+ 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 = GlobalHelper.getEntity(roleRepo, roleId, RoleEntity.class);
|
|
|
+ if (null == roleEntity) {
|
|
|
+ throw new StatusException("003003", "roleId is wrong. roleId=" + roleId);
|
|
|
+ }
|
|
|
+ Role role = new Role(roleEntity.getId(), roleEntity.getCode(),
|
|
|
+ roleEntity.getName());
|
|
|
+ roleList.add(role);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return roleList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public User thirdPartyStudentAccess(Long rootOrgId, String accountType, String accountValue,
|
|
|
+ String appId, String timestamp, String token, String clientIp) throws StatusException {
|
|
|
+
|
|
|
+ OrgEntity rootOrg = GlobalHelper.getEntity(orgRepo, rootOrgId, OrgEntity.class);
|
|
|
+ if (null == rootOrg) {
|
|
|
+ throw new StatusException("003003", "机构不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ ThirdPartyAccessEntity thirdPartyAccess = GlobalHelper.getEntity(thirdPartyAccessRepo,
|
|
|
+ new ThirdPartyAccessPK(rootOrgId, appId), ThirdPartyAccessEntity.class);
|
|
|
+
|
|
|
+ if (null == thirdPartyAccess) {
|
|
|
+ throw new StatusException("003201", "第三方系统接入信息未配置");
|
|
|
+ }
|
|
|
+
|
|
|
+ long timestampLong = 0L;
|
|
|
+ try {
|
|
|
+ timestampLong = Long.parseLong(timestamp);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new StatusException("003202", "timestamp错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ long currentTimeMillis = System.currentTimeMillis();
|
|
|
+ if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccess.getTimeRange()) {
|
|
|
+ throw new StatusException("003203", "timestamp超出时间差范围");
|
|
|
+ }
|
|
|
+
|
|
|
+ String secretKey = thirdPartyAccess.getSecretKey();
|
|
|
+ String joinStr = StringUtil.join(accountType, accountValue, rootOrgId, appId, timestamp,
|
|
|
+ secretKey);
|
|
|
+ byte[] bytes = SHA256.encode(joinStr);
|
|
|
+ String hexAscii = ByteUtil.toHexAscii(bytes);
|
|
|
+
|
|
|
+ if (!hexAscii.equalsIgnoreCase(token)) {
|
|
|
+ throw new StatusException("003204", "token校验失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ AccountType accountTypeEnum = null;
|
|
|
+ try {
|
|
|
+ accountTypeEnum = AccountType.valueOf(accountType);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new StatusException("003204", "accountType is wrong");
|
|
|
+ }
|
|
|
+
|
|
|
+ StudentEntity student = null;
|
|
|
+
|
|
|
+ if (AccountType.STUDENT_PHONE.equals(accountTypeEnum)) {
|
|
|
+ student = studentRepo.findBySecurityPhone(accountValue);
|
|
|
+ } else if (AccountType.STUDENT_CODE.equals(accountTypeEnum)) {
|
|
|
+ StudentCodeEntity scEntity = studentCodeRepo.findByStudentCodeAndRootOrgId(accountValue,
|
|
|
+ rootOrg.getId());
|
|
|
+ if (null != scEntity) {
|
|
|
+ student = GlobalHelper.getEntity(studentRepo, scEntity.getStudentId(),
|
|
|
+ StudentEntity.class);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 学生身份证号登录
|
|
|
+ else if (AccountType.STUDENT_IDENTITY_NUMBER.equals(accountTypeEnum)) {
|
|
|
+ student = studentRepo.findByIdentityNumberAndRootOrgId(accountValue, rootOrg.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null == student) {
|
|
|
+ throw new StatusException("003110", "账号或密码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ LoginInfo loginInfo = new LoginInfo();
|
|
|
+ loginInfo.setAccountType(AccountType.STUDENT_IDENTITY_NUMBER.name());
|
|
|
+ loginInfo.setAccountValue(student.getIdentityNumber());
|
|
|
+ loginInfo.setClientIp(clientIp);
|
|
|
+ loginInfo.setRootOrgId(rootOrgId);
|
|
|
+ loginInfo.setPassword(student.getPassword());
|
|
|
+
|
|
|
+ return login(loginInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public User login(UserType userType, Long userId) {
|
|
|
+
|
|
|
+ User user = new User();
|
|
|
+
|
|
|
+ Long rootOrgId = null;
|
|
|
+
|
|
|
+ if (userType.equals(UserType.STUDENT)) {
|
|
|
+
|
|
|
+ StudentCacheBean student = CacheHelper.getStudent(userId);
|
|
|
+
|
|
|
+ user.setUserId(student.getId());
|
|
|
+ user.setUserType(UserType.STUDENT);
|
|
|
+ user.setDisplayName(student.getName());
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ UserEntity userEntity = GlobalHelper.getEntity(userRepo, userId, UserEntity.class);
|
|
|
+ rootOrgId = userEntity.getRootOrgId();
|
|
|
+
|
|
|
+ user.setUserId(userEntity.getId());
|
|
|
+ user.setUserType(UserType.COMMON);
|
|
|
+ user.setDisplayName(userEntity.getLoginName() + " (" + userEntity.getName() + ")");
|
|
|
+
|
|
|
+ List<Role> roleList = getUserRoles(userEntity.getId());
|
|
|
+ user.setRoleList(roleList);
|
|
|
+ }
|
|
|
+
|
|
|
+ user.setRootOrgId(rootOrgId);
|
|
|
+ OrgCacheBean orgCacheBean = CacheHelper.getOrg(rootOrgId);
|
|
|
+ user.setRootOrgName(orgCacheBean.getName());
|
|
|
+ user.setRootOrgDomain(orgCacheBean.getDomainName());
|
|
|
+
|
|
|
+ setSession(user);
|
|
|
+
|
|
|
+ return user;
|
|
|
+ }
|
|
|
|
|
|
}
|