Selaa lähdekoodia

ip登录错误限制默认10次
系统参数可设置
账号用户错误次数限制 account.failCount
ip错误次数限制 ip.failCount

lijj 1 vuosi sitten
vanhempi
commit
4ad86fab2d

+ 4 - 0
admin/src/main/java/org/springblade/common/cache/CacheNames.java

@@ -57,5 +57,9 @@ public interface CacheNames {
 	 * 登录失败key
 	 */
 	String USER_FAIL_KEY = "blade:user::blade:fail:";
+	/**
+	 * ip登录失败key
+	 */
+	String IP_FAIL_KEY = "blade:ip::blade:fail:";
 
 }

+ 16 - 2
admin/src/main/java/org/springblade/modules/auth/granter/CaptchaTokenGranter.java

@@ -51,7 +51,9 @@ public class CaptchaTokenGranter implements ITokenGranter {
 
 	public static final String GRANT_TYPE = "captcha";
 	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 IP_FAIL_COUNT_VALUE = "ip.failCount";
 
 	private final IUserService userService;
 	private final IRoleService roleService;
@@ -78,13 +80,20 @@ public class CaptchaTokenGranter implements ITokenGranter {
 		String tenantId = tokenParameter.getArgs().getStr("tenantId");
 		String username = tokenParameter.getArgs().getStr("username");
 		String password = tokenParameter.getArgs().getStr("password");
-
+		/** 该用户登录错误次数 */
 		// 判断登录是否锁定
 		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);
 		if (cnt >= failCount) {
 			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;
 		if (Func.isNoneBlank(username, password)) {
@@ -107,11 +116,16 @@ public class CaptchaTokenGranter implements ITokenGranter {
 		if (userInfo == null || userInfo.getUser() == null) {
 			// 增加错误锁定次数
 			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 {
 			// 成功则清除登录缓存
 			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)) {
 			userInfo.getUser().setDeptId(headerDept);

+ 18 - 0
admin/src/main/java/org/springblade/modules/auth/granter/PasswordTokenGranter.java

@@ -50,7 +50,9 @@ public class PasswordTokenGranter implements ITokenGranter {
 
 	public static final String GRANT_TYPE = "password";
 	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 IP_FAIL_COUNT_VALUE = "ip.failCount";
 
 	private final IUserService userService;
 	private final IRoleService roleService;
@@ -70,11 +72,19 @@ public class PasswordTokenGranter implements ITokenGranter {
 		String password = tokenParameter.getArgs().getStr("password");
 
 		// 判断登录是否锁定
+		/** 该用户登录错误次数 */
 		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);
 		if (cnt >= failCount) {
 			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;
 		if (Func.isNoneBlank(username, password)) {
@@ -94,13 +104,21 @@ public class PasswordTokenGranter implements ITokenGranter {
 				userInfo = userService.userInfo(tenantId, username, DigestUtil.hex(password), UserEnum.OTHER);
 			}
 		}
+		/** 用户登录失败次数限制 */
 		if (userInfo == null || userInfo.getUser() == null) {
 			// 增加错误锁定次数
 			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 {
 			// 成功则清除登录错误次数
 			bladeRedis.del(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username));
+			// 成功则则清楚ip错误锁定次数
+			bladeRedis.del(CacheNames.tenantKey(tenantId, CacheNames.IP_FAIL_KEY, currentIp));
 		}
+		/** ip登录错误次数限制 */
+
+
 		// 多部门情况下指定单部门
 		if (Func.isNotEmpty(headerDept) && userInfo != null && userInfo.getUser().getDeptId().contains(headerDept)) {
 			userInfo.getUser().setDeptId(headerDept);

+ 1 - 0
admin/src/main/java/org/springblade/modules/auth/utils/TokenUtil.java

@@ -57,6 +57,7 @@ public class TokenUtil {
 	public final static String USER_HAS_NO_TENANT = "未获得用户的租户信息";
 	public final static String USER_HAS_NO_TENANT_PERMISSION = "租户授权已过期,请联系管理员";
 	public final static String USER_HAS_TOO_MANY_FAILS = "登录错误次数过多,请稍后再试";
+	public final static String IP_HAS_TOO_MANY_FAILS = "当前ip地址登录错误次数过多,请稍后再试";
 	public final static String HEADER_KEY = "Authorization";
 	public final static String HEADER_PREFIX = "Basic ";
 	public final static String DEFAULT_AVATAR = "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png";

+ 2 - 0
admin_ui/src/page/login/userlogin.vue

@@ -235,6 +235,7 @@ export default {
           this.$store
             .dispatch('LoginByUsername', this.loginForm)
             .then(() => {
+              debugger
               if (this.website.switchMode) {
                 const deptId = this.userInfo.dept_id;
                 const roleId = this.userInfo.role_id;
@@ -250,6 +251,7 @@ export default {
               }
               loading.close();
               this.$router.push(this.tagWel);
+              this.refreshCode();
             })
             .catch(err => {
               console.log(err);