|
@@ -51,7 +51,9 @@ public class CaptchaTokenGranter implements ITokenGranter {
|
|
|
|
|
|
|
|
public static final String GRANT_TYPE = "captcha";
|
|
public static final String GRANT_TYPE = "captcha";
|
|
|
public static final Integer FAIL_COUNT = 5;
|
|
public static final Integer FAIL_COUNT = 5;
|
|
|
|
|
+ public static final Integer IP_FAIL_COUNT = 10;
|
|
|
public static final String FAIL_COUNT_VALUE = "account.failCount";
|
|
public static final String FAIL_COUNT_VALUE = "account.failCount";
|
|
|
|
|
+ public static final String IP_FAIL_COUNT_VALUE = "ip.failCount";
|
|
|
|
|
|
|
|
private final IUserService userService;
|
|
private final IUserService userService;
|
|
|
private final IRoleService roleService;
|
|
private final IRoleService roleService;
|
|
@@ -78,13 +80,20 @@ public class CaptchaTokenGranter implements ITokenGranter {
|
|
|
String tenantId = tokenParameter.getArgs().getStr("tenantId");
|
|
String tenantId = tokenParameter.getArgs().getStr("tenantId");
|
|
|
String username = tokenParameter.getArgs().getStr("username");
|
|
String username = tokenParameter.getArgs().getStr("username");
|
|
|
String password = tokenParameter.getArgs().getStr("password");
|
|
String password = tokenParameter.getArgs().getStr("password");
|
|
|
-
|
|
|
|
|
|
|
+ /** 该用户登录错误次数 */
|
|
|
// 判断登录是否锁定
|
|
// 判断登录是否锁定
|
|
|
int cnt = Func.toInt(bladeRedis.get(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username)), 0);
|
|
int cnt = Func.toInt(bladeRedis.get(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username)), 0);
|
|
|
int failCount = Func.toInt(ParamCache.getValue(FAIL_COUNT_VALUE), FAIL_COUNT);
|
|
int failCount = Func.toInt(ParamCache.getValue(FAIL_COUNT_VALUE), FAIL_COUNT);
|
|
|
if (cnt >= failCount) {
|
|
if (cnt >= failCount) {
|
|
|
throw new ServiceException(TokenUtil.USER_HAS_TOO_MANY_FAILS);
|
|
throw new ServiceException(TokenUtil.USER_HAS_TOO_MANY_FAILS);
|
|
|
}
|
|
}
|
|
|
|
|
+ /** 同ip下登录错误次数 */
|
|
|
|
|
+ String currentIp = WebUtil.getIP();
|
|
|
|
|
+ int ifc = Func.toInt(bladeRedis.get(CacheNames.tenantKey(tenantId, CacheNames.IP_FAIL_KEY, currentIp)), 0);
|
|
|
|
|
+ int ipFailCount = Func.toInt(ParamCache.getValue(IP_FAIL_COUNT_VALUE), IP_FAIL_COUNT);
|
|
|
|
|
+ if (ifc >= ipFailCount) {
|
|
|
|
|
+ throw new ServiceException(TokenUtil.IP_HAS_TOO_MANY_FAILS);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
UserInfo userInfo = null;
|
|
UserInfo userInfo = null;
|
|
|
if (Func.isNoneBlank(username, password)) {
|
|
if (Func.isNoneBlank(username, password)) {
|
|
@@ -107,11 +116,16 @@ public class CaptchaTokenGranter implements ITokenGranter {
|
|
|
if (userInfo == null || userInfo.getUser() == null) {
|
|
if (userInfo == null || userInfo.getUser() == null) {
|
|
|
// 增加错误锁定次数
|
|
// 增加错误锁定次数
|
|
|
bladeRedis.setEx(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username), cnt + 1, Duration.ofMinutes(30));
|
|
bladeRedis.setEx(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username), cnt + 1, Duration.ofMinutes(30));
|
|
|
|
|
+ // 增加ip错误锁定次数
|
|
|
|
|
+ bladeRedis.setEx(CacheNames.tenantKey(tenantId, CacheNames.IP_FAIL_KEY, currentIp), ifc + 1, Duration.ofMinutes(30));
|
|
|
} else {
|
|
} else {
|
|
|
// 成功则清除登录缓存
|
|
// 成功则清除登录缓存
|
|
|
bladeRedis.del(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username));
|
|
bladeRedis.del(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username));
|
|
|
- bladeRedis.del(CacheNames.CAPTCHA_KEY + key);
|
|
|
|
|
|
|
+ // 成功则则清楚ip错误锁定次数
|
|
|
|
|
+ bladeRedis.del(CacheNames.tenantKey(tenantId, CacheNames.IP_FAIL_KEY, currentIp));
|
|
|
}
|
|
}
|
|
|
|
|
+ // 无论成功与否都要使验证码失效
|
|
|
|
|
+ bladeRedis.del(CacheNames.CAPTCHA_KEY + key);
|
|
|
// 多部门情况下指定单部门
|
|
// 多部门情况下指定单部门
|
|
|
if (Func.isNotEmpty(headerDept) && userInfo != null && userInfo.getUser().getDeptId().contains(headerDept)) {
|
|
if (Func.isNotEmpty(headerDept) && userInfo != null && userInfo.getUser().getDeptId().contains(headerDept)) {
|
|
|
userInfo.getUser().setDeptId(headerDept);
|
|
userInfo.getUser().setDeptId(headerDept);
|