fix 修复 登录错误锁定不区分租户问题
This commit is contained in:
parent
588a47897a
commit
b886f3a04b
@ -4,13 +4,14 @@ import cn.dev33.satoken.exception.NotLoginException;
|
|||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Opt;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.baomidou.lock.annotation.Lock4j;
|
import com.baomidou.lock.annotation.Lock4j;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.zhyd.oauth.model.AuthUser;
|
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.Constants;
|
||||||
import org.dromara.common.core.constant.GlobalConstants;
|
|
||||||
import org.dromara.common.core.constant.TenantConstants;
|
import org.dromara.common.core.constant.TenantConstants;
|
||||||
import org.dromara.common.core.domain.dto.RoleDTO;
|
import org.dromara.common.core.domain.dto.RoleDTO;
|
||||||
import org.dromara.common.core.domain.model.LoginUser;
|
import org.dromara.common.core.domain.model.LoginUser;
|
||||||
@ -155,16 +156,11 @@ public class SysLoginService {
|
|||||||
loginUser.setUserType(user.getUserType());
|
loginUser.setUserType(user.getUserType());
|
||||||
loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
|
loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
|
||||||
loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
|
loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
|
||||||
TenantHelper.dynamic(user.getTenantId(), () -> {
|
Opt<SysDeptVo> deptOpt = Opt.of(user.getDeptId()).map(deptService::selectDeptById);
|
||||||
SysDeptVo dept = null;
|
loginUser.setDeptName(deptOpt.map(SysDeptVo::getDeptName).orElse(StringUtils.EMPTY));
|
||||||
if (ObjectUtil.isNotNull(user.getDeptId())) {
|
loginUser.setDeptCategory(deptOpt.map(SysDeptVo::getDeptCategory).orElse(StringUtils.EMPTY));
|
||||||
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());
|
List<SysRoleVo> roles = roleService.selectRolesByUserId(user.getUserId());
|
||||||
loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class));
|
loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class));
|
||||||
});
|
|
||||||
return loginUser;
|
return loginUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +182,7 @@ public class SysLoginService {
|
|||||||
* 登录校验
|
* 登录校验
|
||||||
*/
|
*/
|
||||||
public void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) {
|
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;
|
String loginFail = Constants.LOGIN_FAIL;
|
||||||
|
|
||||||
// 获取用户登录错误次数,默认为0 (可自定义限制策略 例如: key + username + ip)
|
// 获取用户登录错误次数,默认为0 (可自定义限制策略 例如: key + username + ip)
|
||||||
|
@ -21,7 +21,6 @@ import org.dromara.common.json.utils.JsonUtils;
|
|||||||
import org.dromara.common.redis.utils.RedisUtils;
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.common.tenant.helper.TenantHelper;
|
import org.dromara.common.tenant.helper.TenantHelper;
|
||||||
import org.dromara.system.domain.SysClient;
|
|
||||||
import org.dromara.system.domain.SysUser;
|
import org.dromara.system.domain.SysUser;
|
||||||
import org.dromara.system.domain.vo.SysClientVo;
|
import org.dromara.system.domain.vo.SysClientVo;
|
||||||
import org.dromara.system.domain.vo.SysUserVo;
|
import org.dromara.system.domain.vo.SysUserVo;
|
||||||
@ -51,13 +50,12 @@ public class EmailAuthStrategy implements IAuthStrategy {
|
|||||||
String tenantId = loginBody.getTenantId();
|
String tenantId = loginBody.getTenantId();
|
||||||
String email = loginBody.getEmail();
|
String email = loginBody.getEmail();
|
||||||
String emailCode = loginBody.getEmailCode();
|
String emailCode = loginBody.getEmailCode();
|
||||||
|
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
|
||||||
// 通过邮箱查找用户
|
SysUserVo user = loadUserByEmail(email);
|
||||||
SysUserVo user = loadUserByEmail(tenantId, email);
|
|
||||||
|
|
||||||
loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
|
loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
|
||||||
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
|
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
|
||||||
LoginUser loginUser = loginService.buildLoginUser(user);
|
return loginService.buildLoginUser(user);
|
||||||
|
});
|
||||||
loginUser.setClientKey(client.getClientKey());
|
loginUser.setClientKey(client.getClientKey());
|
||||||
loginUser.setDeviceType(client.getDeviceType());
|
loginUser.setDeviceType(client.getDeviceType());
|
||||||
SaLoginModel model = new SaLoginModel();
|
SaLoginModel model = new SaLoginModel();
|
||||||
@ -89,8 +87,7 @@ public class EmailAuthStrategy implements IAuthStrategy {
|
|||||||
return code.equals(emailCode);
|
return code.equals(emailCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SysUserVo loadUserByEmail(String tenantId, String email) {
|
private SysUserVo loadUserByEmail(String email) {
|
||||||
return TenantHelper.dynamic(tenantId, () -> {
|
|
||||||
SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, email));
|
SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, email));
|
||||||
if (ObjectUtil.isNull(user)) {
|
if (ObjectUtil.isNull(user)) {
|
||||||
log.info("登录用户:{} 不存在.", email);
|
log.info("登录用户:{} 不存在.", email);
|
||||||
@ -100,7 +97,6 @@ public class EmailAuthStrategy implements IAuthStrategy {
|
|||||||
throw new UserException("user.blocked", email);
|
throw new UserException("user.blocked", email);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,11 +62,12 @@ public class PasswordAuthStrategy implements IAuthStrategy {
|
|||||||
if (captchaEnabled) {
|
if (captchaEnabled) {
|
||||||
validateCaptcha(tenantId, username, code, uuid);
|
validateCaptcha(tenantId, username, code, uuid);
|
||||||
}
|
}
|
||||||
|
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
|
||||||
SysUserVo user = loadUserByUsername(tenantId, username);
|
SysUserVo user = loadUserByUsername(username);
|
||||||
loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
|
loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
|
||||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||||
LoginUser loginUser = loginService.buildLoginUser(user);
|
return loginService.buildLoginUser(user);
|
||||||
|
});
|
||||||
loginUser.setClientKey(client.getClientKey());
|
loginUser.setClientKey(client.getClientKey());
|
||||||
loginUser.setDeviceType(client.getDeviceType());
|
loginUser.setDeviceType(client.getDeviceType());
|
||||||
SaLoginModel model = new SaLoginModel();
|
SaLoginModel model = new SaLoginModel();
|
||||||
@ -107,8 +108,7 @@ public class PasswordAuthStrategy implements IAuthStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SysUserVo loadUserByUsername(String tenantId, String username) {
|
private SysUserVo loadUserByUsername(String username) {
|
||||||
return TenantHelper.dynamic(tenantId, () -> {
|
|
||||||
SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username));
|
SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username));
|
||||||
if (ObjectUtil.isNull(user)) {
|
if (ObjectUtil.isNull(user)) {
|
||||||
log.info("登录用户:{} 不存在.", username);
|
log.info("登录用户:{} 不存在.", username);
|
||||||
@ -118,7 +118,6 @@ public class PasswordAuthStrategy implements IAuthStrategy {
|
|||||||
throw new UserException("user.blocked", username);
|
throw new UserException("user.blocked", username);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import org.dromara.common.json.utils.JsonUtils;
|
|||||||
import org.dromara.common.redis.utils.RedisUtils;
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.common.tenant.helper.TenantHelper;
|
import org.dromara.common.tenant.helper.TenantHelper;
|
||||||
import org.dromara.system.domain.SysClient;
|
|
||||||
import org.dromara.system.domain.SysUser;
|
import org.dromara.system.domain.SysUser;
|
||||||
import org.dromara.system.domain.vo.SysClientVo;
|
import org.dromara.system.domain.vo.SysClientVo;
|
||||||
import org.dromara.system.domain.vo.SysUserVo;
|
import org.dromara.system.domain.vo.SysUserVo;
|
||||||
@ -51,13 +50,12 @@ public class SmsAuthStrategy implements IAuthStrategy {
|
|||||||
String tenantId = loginBody.getTenantId();
|
String tenantId = loginBody.getTenantId();
|
||||||
String phonenumber = loginBody.getPhonenumber();
|
String phonenumber = loginBody.getPhonenumber();
|
||||||
String smsCode = loginBody.getSmsCode();
|
String smsCode = loginBody.getSmsCode();
|
||||||
|
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
|
||||||
// 通过手机号查找用户
|
SysUserVo user = loadUserByPhonenumber(phonenumber);
|
||||||
SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber);
|
|
||||||
|
|
||||||
loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
|
loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
|
||||||
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
|
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
|
||||||
LoginUser loginUser = loginService.buildLoginUser(user);
|
return loginService.buildLoginUser(user);
|
||||||
|
});
|
||||||
loginUser.setClientKey(client.getClientKey());
|
loginUser.setClientKey(client.getClientKey());
|
||||||
loginUser.setDeviceType(client.getDeviceType());
|
loginUser.setDeviceType(client.getDeviceType());
|
||||||
SaLoginModel model = new SaLoginModel();
|
SaLoginModel model = new SaLoginModel();
|
||||||
@ -89,8 +87,7 @@ public class SmsAuthStrategy implements IAuthStrategy {
|
|||||||
return code.equals(smsCode);
|
return code.equals(smsCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) {
|
private SysUserVo loadUserByPhonenumber(String phonenumber) {
|
||||||
return TenantHelper.dynamic(tenantId, () -> {
|
|
||||||
SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber));
|
SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber));
|
||||||
if (ObjectUtil.isNull(user)) {
|
if (ObjectUtil.isNull(user)) {
|
||||||
log.info("登录用户:{} 不存在.", phonenumber);
|
log.info("登录用户:{} 不存在.", phonenumber);
|
||||||
@ -100,7 +97,6 @@ public class SmsAuthStrategy implements IAuthStrategy {
|
|||||||
throw new UserException("user.blocked", phonenumber);
|
throw new UserException("user.blocked", phonenumber);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -92,11 +92,11 @@ public class SocialAuthStrategy implements IAuthStrategy {
|
|||||||
} else {
|
} else {
|
||||||
social = list.get(0);
|
social = list.get(0);
|
||||||
}
|
}
|
||||||
// 查找用户
|
LoginUser loginUser = TenantHelper.dynamic(social.getTenantId(), () -> {
|
||||||
SysUserVo user = loadUser(social.getTenantId(), social.getUserId());
|
SysUserVo user = loadUser(social.getUserId());
|
||||||
|
|
||||||
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
|
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
|
||||||
LoginUser loginUser = loginService.buildLoginUser(user);
|
return loginService.buildLoginUser(user);
|
||||||
|
});
|
||||||
loginUser.setClientKey(client.getClientKey());
|
loginUser.setClientKey(client.getClientKey());
|
||||||
loginUser.setDeviceType(client.getDeviceType());
|
loginUser.setDeviceType(client.getDeviceType());
|
||||||
SaLoginModel model = new SaLoginModel();
|
SaLoginModel model = new SaLoginModel();
|
||||||
@ -116,8 +116,7 @@ public class SocialAuthStrategy implements IAuthStrategy {
|
|||||||
return loginVo;
|
return loginVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SysUserVo loadUser(String tenantId, Long userId) {
|
private SysUserVo loadUser(Long userId) {
|
||||||
return TenantHelper.dynamic(tenantId, () -> {
|
|
||||||
SysUserVo user = userMapper.selectVoById(userId);
|
SysUserVo user = userMapper.selectVoById(userId);
|
||||||
if (ObjectUtil.isNull(user)) {
|
if (ObjectUtil.isNull(user)) {
|
||||||
log.info("登录用户:{} 不存在.", "");
|
log.info("登录用户:{} 不存在.", "");
|
||||||
@ -127,7 +126,6 @@ public class SocialAuthStrategy implements IAuthStrategy {
|
|||||||
throw new UserException("user.blocked", "");
|
throw new UserException("user.blocked", "");
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,4 +22,9 @@ public interface CacheConstants {
|
|||||||
*/
|
*/
|
||||||
String SYS_DICT_KEY = "sys_dict:";
|
String SYS_DICT_KEY = "sys_dict:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录账户密码错误次数 redis key
|
||||||
|
*/
|
||||||
|
String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,6 @@ public interface GlobalConstants {
|
|||||||
*/
|
*/
|
||||||
String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:";
|
String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:";
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录账户密码错误次数 redis key
|
|
||||||
*/
|
|
||||||
String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 三方认证 redis key
|
* 三方认证 redis key
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package org.dromara.system.controller.monitor;
|
package org.dromara.system.controller.monitor;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
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.core.domain.R;
|
||||||
import org.dromara.common.excel.utils.ExcelUtil;
|
import org.dromara.common.excel.utils.ExcelUtil;
|
||||||
import org.dromara.common.log.annotation.Log;
|
import org.dromara.common.log.annotation.Log;
|
||||||
@ -13,8 +15,6 @@ import org.dromara.common.web.core.BaseController;
|
|||||||
import org.dromara.system.domain.bo.SysLogininforBo;
|
import org.dromara.system.domain.bo.SysLogininforBo;
|
||||||
import org.dromara.system.domain.vo.SysLogininforVo;
|
import org.dromara.system.domain.vo.SysLogininforVo;
|
||||||
import org.dromara.system.service.ISysLogininforService;
|
import org.dromara.system.service.ISysLogininforService;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ public class SysLogininforController extends BaseController {
|
|||||||
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
|
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
|
||||||
@GetMapping("/unlock/{userName}")
|
@GetMapping("/unlock/{userName}")
|
||||||
public R<Void> unlock(@PathVariable("userName") String 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)) {
|
if (RedisUtils.hasKey(loginName)) {
|
||||||
RedisUtils.deleteObject(loginName);
|
RedisUtils.deleteObject(loginName);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user