diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java index ddd6bfb5..b5d1d0f8 100644 --- a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java @@ -1,5 +1,7 @@ package com.ruoyi.auth.service; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.redis.service.RedisService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.ruoyi.common.core.constant.Constants; @@ -18,9 +20,12 @@ import com.ruoyi.system.api.domain.SysLogininfor; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.model.LoginUser; +import java.util.Date; +import java.util.concurrent.TimeUnit; + /** * 登录校验方法 - * + * * @author ruoyi */ @Component @@ -32,6 +37,9 @@ public class SysLoginService @Autowired private RemoteUserService remoteUserService; + @Autowired + private RedisService redisService; + /** * 登录 */ @@ -87,6 +95,7 @@ public class SysLoginService recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码错误"); throw new ServiceException("用户不存在/密码错误"); } + recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"); return userInfo; } @@ -133,7 +142,7 @@ public class SysLoginService /** * 记录登录信息 - * + * * @param username 用户名 * @param status 状态 * @param message 消息内容 @@ -155,5 +164,40 @@ public class SysLoginService logininfor.setStatus("1"); } remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER); + + //记录错误次数, 防止无限重试,进行暴力破解 + recordLoginErrorTimes(username, status); + } + + /** + * @author dazer + * @date 2022-01-21 + * 记录username错误次数,超过指定次数 锁定xx分钟,防止暴力破解 + * @param username 登录用户名 + * @param status {@link Constants#LOGIN_SUCCESS} + * {@link Constants#LOGIN_FAIL} + */ + private void recordLoginErrorTimes(String username, String status) + { + String loginErrorTimesKey = CacheConstants.REDIS_KEY_ERROR_TIMES + username; + Long redisKeyTimeout = 30L; + long maxErrorTimes = 5L; + + if (Constants.LOGIN_SUCCESS.equals(status)) { + redisService.deleteObject(loginErrorTimesKey); + } else if (Constants.LOGIN_FAIL.equals(status)) { + Integer errorTimes = redisService.getCacheObject(loginErrorTimesKey); + if (errorTimes == null) { + errorTimes = 0; + } + // 登录错误,进行累加错误次数 + errorTimes++; + // 登录错误,缓存:30分钟 + redisService.setCacheObject(loginErrorTimesKey, errorTimes, redisKeyTimeout, TimeUnit.MINUTES); + // 连续错误5次,进行账号锁定 + if (errorTimes >= maxErrorTimes) { + throw new ServiceException("用户名密码错误次数已达上限,账号已被锁定请" + redisKeyTimeout + "分钟后再试!"); + } + } } -} \ No newline at end of file +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java index 913a891d..1896c150 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java @@ -2,7 +2,7 @@ package com.ruoyi.common.core.constant; /** * 缓存的key 常量 - * + * * @author ruoyi */ public class CacheConstants @@ -21,4 +21,9 @@ public class CacheConstants * 权限缓存前缀 */ public final static String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * username登录错误次数的 redis key + */ + public final static String REDIS_KEY_ERROR_TIMES = "login:error:times:"; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 43d6e8cb..40655934 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -4,6 +4,9 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import javax.validation.Validator; + +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.redis.service.RedisService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,7 +35,7 @@ import com.ruoyi.system.service.ISysUserService; /** * 用户 业务层处理 - * + * * @author ruoyi */ @Service @@ -61,9 +64,12 @@ public class SysUserServiceImpl implements ISysUserService @Autowired protected Validator validator; + @Autowired + private RedisService redisService; + /** * 根据条件分页查询用户列表 - * + * * @param user 用户信息 * @return 用户信息集合信息 */ @@ -76,7 +82,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 根据条件分页查询已分配用户角色列表 - * + * * @param user 用户信息 * @return 用户信息集合信息 */ @@ -89,7 +95,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 根据条件分页查询未分配用户角色列表 - * + * * @param user 用户信息 * @return 用户信息集合信息 */ @@ -102,7 +108,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 通过用户名查询用户 - * + * * @param userName 用户名 * @return 用户对象信息 */ @@ -114,7 +120,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 通过用户ID查询用户 - * + * * @param userId 用户ID * @return 用户对象信息 */ @@ -126,7 +132,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 查询用户所属角色组 - * + * * @param userName 用户名 * @return 结果 */ @@ -143,7 +149,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 查询用户所属岗位组 - * + * * @param userName 用户名 * @return 结果 */ @@ -160,7 +166,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 校验用户名称是否唯一 - * + * * @param userName 用户名称 * @return 结果 */ @@ -213,7 +219,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 校验用户是否允许操作 - * + * * @param user 用户信息 */ @Override @@ -227,7 +233,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 校验用户是否有数据权限 - * + * * @param userId 用户id */ @Override @@ -247,7 +253,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 新增保存用户信息 - * + * * @param user 用户信息 * @return 结果 */ @@ -266,7 +272,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 注册用户信息 - * + * * @param user 用户信息 * @return 结果 */ @@ -278,7 +284,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 修改保存用户信息 - * + * * @param user 用户信息 * @return 结果 */ @@ -300,7 +306,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 用户授权角色 - * + * * @param userId 用户ID * @param roleIds 角色组 */ @@ -314,7 +320,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 修改用户状态 - * + * * @param user 用户信息 * @return 结果 */ @@ -326,7 +332,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 修改用户基本信息 - * + * * @param user 用户信息 * @return 结果 */ @@ -338,7 +344,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 修改用户头像 - * + * * @param userName 用户名 * @param avatar 头像地址 * @return 结果 @@ -351,19 +357,22 @@ public class SysUserServiceImpl implements ISysUserService /** * 重置用户密码 - * + * * @param user 用户信息 * @return 结果 */ @Override public int resetPwd(SysUser user) { + // 重置密码的时候,同步删除 登录错误次数 缓存 + redisService.deleteObject(CacheConstants.REDIS_KEY_ERROR_TIMES + user.getUserName()); + return userMapper.updateUser(user); } /** * 重置用户密码 - * + * * @param userName 用户名 * @param password 密码 * @return 结果 @@ -371,12 +380,15 @@ public class SysUserServiceImpl implements ISysUserService @Override public int resetUserPwd(String userName, String password) { + // 重置密码的时候,同步删除 登录错误次数 缓存 + redisService.deleteObject(CacheConstants.REDIS_KEY_ERROR_TIMES + userName); + return userMapper.resetUserPwd(userName, password); } /** * 新增用户角色信息 - * + * * @param user 用户对象 */ public void insertUserRole(SysUser user) @@ -402,7 +414,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 新增用户岗位信息 - * + * * @param user 用户对象 */ public void insertUserPost(SysUser user) @@ -428,7 +440,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 新增用户角色信息 - * + * * @param userId 用户ID * @param roleIds 角色组 */ @@ -454,7 +466,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 通过用户ID删除用户 - * + * * @param userId 用户ID * @return 结果 */ @@ -471,7 +483,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 批量删除用户信息 - * + * * @param userIds 需要删除的用户ID * @return 结果 */ @@ -493,7 +505,7 @@ public class SysUserServiceImpl implements ISysUserService /** * 导入用户数据 - * + * * @param userList 用户数据列表 * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 * @param operName 操作用户