| | |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.lang.Opt; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.lock.annotation.Lock4j; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.zhyd.oauth.model.AuthUser; |
| | | import org.dromara.common.core.constant.CacheConstants; |
| | | import org.dromara.common.core.constant.Constants; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.core.constant.TenantConstants; |
| | | import org.dromara.common.core.domain.dto.RoleDTO; |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | |
| | | loginUser.setUserType(user.getUserType()); |
| | | loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); |
| | | loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); |
| | | TenantHelper.dynamic(user.getTenantId(), () -> { |
| | | SysDeptVo dept = null; |
| | | if (ObjectUtil.isNotNull(user.getDeptId())) { |
| | | dept = deptService.selectDeptById(user.getDeptId()); |
| | | } |
| | | loginUser.setDeptName(ObjectUtil.isNull(dept) ? "" : dept.getDeptName()); |
| | | loginUser.setDeptCategory(ObjectUtil.isNull(dept) ? "" : dept.getDeptCategory()); |
| | | List<SysRoleVo> roles = roleService.selectRolesByUserId(user.getUserId()); |
| | | loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class)); |
| | | }); |
| | | Opt<SysDeptVo> deptOpt = Opt.of(user.getDeptId()).map(deptService::selectDeptById); |
| | | loginUser.setDeptName(deptOpt.map(SysDeptVo::getDeptName).orElse(StringUtils.EMPTY)); |
| | | loginUser.setDeptCategory(deptOpt.map(SysDeptVo::getDeptCategory).orElse(StringUtils.EMPTY)); |
| | | List<SysRoleVo> roles = roleService.selectRolesByUserId(user.getUserId()); |
| | | loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class)); |
| | | return loginUser; |
| | | } |
| | | |
| | |
| | | * 登录校验 |
| | | */ |
| | | public void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) { |
| | | String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username; |
| | | String errorKey = CacheConstants.PWD_ERR_CNT_KEY + username; |
| | | String loginFail = Constants.LOGIN_FAIL; |
| | | |
| | | // 获取用户登录错误次数,默认为0 (可自定义限制策略 例如: key + username + ip) |
| | |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | |
| | | String tenantId = loginBody.getTenantId(); |
| | | String email = loginBody.getEmail(); |
| | | String emailCode = loginBody.getEmailCode(); |
| | | |
| | | // 通过邮箱查找用户 |
| | | SysUserVo user = loadUserByEmail(tenantId, email); |
| | | |
| | | loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode)); |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 |
| | | LoginUser loginUser = loginService.buildLoginUser(user); |
| | | LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> { |
| | | SysUserVo user = loadUserByEmail(email); |
| | | loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode)); |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 |
| | | return loginService.buildLoginUser(user); |
| | | }); |
| | | loginUser.setClientKey(client.getClientKey()); |
| | | loginUser.setDeviceType(client.getDeviceType()); |
| | | SaLoginModel model = new SaLoginModel(); |
| | |
| | | return code.equals(emailCode); |
| | | } |
| | | |
| | | private SysUserVo loadUserByEmail(String tenantId, String email) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, email)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", email); |
| | | throw new UserException("user.not.exists", email); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", email); |
| | | throw new UserException("user.blocked", email); |
| | | } |
| | | return user; |
| | | }); |
| | | private SysUserVo loadUserByEmail(String email) { |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, email)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", email); |
| | | throw new UserException("user.not.exists", email); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", email); |
| | | throw new UserException("user.blocked", email); |
| | | } |
| | | return user; |
| | | } |
| | | |
| | | } |
| | |
| | | if (captchaEnabled) { |
| | | validateCaptcha(tenantId, username, code, uuid); |
| | | } |
| | | |
| | | SysUserVo user = loadUserByUsername(tenantId, username); |
| | | loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword())); |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser |
| | | LoginUser loginUser = loginService.buildLoginUser(user); |
| | | LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> { |
| | | SysUserVo user = loadUserByUsername(username); |
| | | loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword())); |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser |
| | | return loginService.buildLoginUser(user); |
| | | }); |
| | | loginUser.setClientKey(client.getClientKey()); |
| | | loginUser.setDeviceType(client.getDeviceType()); |
| | | SaLoginModel model = new SaLoginModel(); |
| | |
| | | } |
| | | } |
| | | |
| | | private SysUserVo loadUserByUsername(String tenantId, String username) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", username); |
| | | throw new UserException("user.not.exists", username); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", username); |
| | | throw new UserException("user.blocked", username); |
| | | } |
| | | return user; |
| | | }); |
| | | private SysUserVo loadUserByUsername(String username) { |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", username); |
| | | throw new UserException("user.not.exists", username); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", username); |
| | | throw new UserException("user.blocked", username); |
| | | } |
| | | return user; |
| | | } |
| | | |
| | | } |
| | |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.common.tenant.helper.TenantHelper; |
| | | import org.dromara.system.domain.SysClient; |
| | | import org.dromara.system.domain.SysUser; |
| | | import org.dromara.system.domain.vo.SysClientVo; |
| | | import org.dromara.system.domain.vo.SysUserVo; |
| | |
| | | String tenantId = loginBody.getTenantId(); |
| | | String phonenumber = loginBody.getPhonenumber(); |
| | | String smsCode = loginBody.getSmsCode(); |
| | | |
| | | // 通过手机号查找用户 |
| | | SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber); |
| | | |
| | | loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode)); |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 |
| | | LoginUser loginUser = loginService.buildLoginUser(user); |
| | | LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> { |
| | | SysUserVo user = loadUserByPhonenumber(phonenumber); |
| | | loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode)); |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 |
| | | return loginService.buildLoginUser(user); |
| | | }); |
| | | loginUser.setClientKey(client.getClientKey()); |
| | | loginUser.setDeviceType(client.getDeviceType()); |
| | | SaLoginModel model = new SaLoginModel(); |
| | |
| | | return code.equals(smsCode); |
| | | } |
| | | |
| | | private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", phonenumber); |
| | | throw new UserException("user.not.exists", phonenumber); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", phonenumber); |
| | | throw new UserException("user.blocked", phonenumber); |
| | | } |
| | | return user; |
| | | }); |
| | | private SysUserVo loadUserByPhonenumber(String phonenumber) { |
| | | SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber)); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", phonenumber); |
| | | throw new UserException("user.not.exists", phonenumber); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", phonenumber); |
| | | throw new UserException("user.blocked", phonenumber); |
| | | } |
| | | return user; |
| | | } |
| | | |
| | | } |
| | |
| | | } else { |
| | | social = list.get(0); |
| | | } |
| | | // 查找用户 |
| | | SysUserVo user = loadUser(social.getTenantId(), social.getUserId()); |
| | | |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 |
| | | LoginUser loginUser = loginService.buildLoginUser(user); |
| | | LoginUser loginUser = TenantHelper.dynamic(social.getTenantId(), () -> { |
| | | SysUserVo user = loadUser(social.getUserId()); |
| | | // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 |
| | | return loginService.buildLoginUser(user); |
| | | }); |
| | | loginUser.setClientKey(client.getClientKey()); |
| | | loginUser.setDeviceType(client.getDeviceType()); |
| | | SaLoginModel model = new SaLoginModel(); |
| | |
| | | return loginVo; |
| | | } |
| | | |
| | | private SysUserVo loadUser(String tenantId, Long userId) { |
| | | return TenantHelper.dynamic(tenantId, () -> { |
| | | SysUserVo user = userMapper.selectVoById(userId); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", ""); |
| | | throw new UserException("user.not.exists", ""); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", ""); |
| | | throw new UserException("user.blocked", ""); |
| | | } |
| | | return user; |
| | | }); |
| | | private SysUserVo loadUser(Long userId) { |
| | | SysUserVo user = userMapper.selectVoById(userId); |
| | | if (ObjectUtil.isNull(user)) { |
| | | log.info("登录用户:{} 不存在.", ""); |
| | | throw new UserException("user.not.exists", ""); |
| | | } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | log.info("登录用户:{} 已被停用.", ""); |
| | | throw new UserException("user.blocked", ""); |
| | | } |
| | | return user; |
| | | } |
| | | |
| | | } |
| | |
| | | */ |
| | | String SYS_DICT_KEY = "sys_dict:"; |
| | | |
| | | /** |
| | | * 登录账户密码错误次数 redis key |
| | | */ |
| | | String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; |
| | | |
| | | } |
| | |
| | | String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:"; |
| | | |
| | | /** |
| | | * 登录账户密码错误次数 redis key |
| | | */ |
| | | String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:"; |
| | | |
| | | /** |
| | | * 三方认证 redis key |
| | | */ |
| | | String SOCIAL_AUTH_CODE_KEY = GLOBAL_REDIS_KEY + "social_auth_codes:"; |
| | |
| | | package org.dromara.system.controller.monitor; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.CacheConstants; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.excel.utils.ExcelUtil; |
| | | import org.dromara.common.log.annotation.Log; |
| | |
| | | import org.dromara.system.domain.bo.SysLogininforBo; |
| | | import org.dromara.system.domain.vo.SysLogininforVo; |
| | | import org.dromara.system.service.ISysLogininforService; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | |
| | | @Log(title = "账户解锁", businessType = BusinessType.OTHER) |
| | | @GetMapping("/unlock/{userName}") |
| | | public R<Void> unlock(@PathVariable("userName") String userName) { |
| | | String loginName = GlobalConstants.PWD_ERR_CNT_KEY + userName; |
| | | String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; |
| | | if (RedisUtils.hasKey(loginName)) { |
| | | RedisUtils.deleteObject(loginName); |
| | | } |