Commit f232a9aa authored by 技术部-任文超's avatar 技术部-任文超

优化代码,完善锁定策略,阈值设为:1分钟60次,锁定6小时

parent f8bf9d77
......@@ -38,6 +38,10 @@ public interface Constants {
final Long Image_Need_Count=3L;
String REDIS_PASSWORD_ERROR_COUNT = "password_error_count:";
String REDIS_PASSWORD_ERROR_COUNT_FOR_IPV4 = "password_error_count_4_ipv4:";
String IPV4_LOCK = "lock_ipv4:";
final Long IPV4_LOCK_MINUTES = 6 * 60L;
final Long IPV4_COUNT_MINUTES = 1L;
final Long IPV4_LOCK_ON_COUNTS = 60L;
/**
* redis中token的key值前缀
*/
......
......@@ -45,7 +45,7 @@ public class PasswordErrorFiniteValidateAdvisor {
}
/**
* 在受保护的接口方法执行前, 执行密码错误限次校验
* 在受保护的接口方法执行前, 执行锁状态校验
*
* @param pjp
* @return
......@@ -56,29 +56,17 @@ public class PasswordErrorFiniteValidateAdvisor {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 客户端IP
String clientIp = getIp(request);
Long countErrorByIp = getIpv4Count(clientIp);
// 5分钟内不超过3次
if(countErrorByIp > Constants.Image_Need_Count){
String lockIpv4Key = getLockIpv4Key(clientIp);
String lock = redisTemplate.opsForValue().get(lockIpv4Key);
if (Objects.equals(Boolean.TRUE.toString(), lock)){
LOGGER.info("Locked ip access:{}", clientIp);
return JsonResult.buildErrorStateResult("登录失败", null);
}
return pjp.proceed();
}
// 获取该ipv4密码错误计数器
private Long getIpv4Count(String ipv4) {
if (ValidationUtil.validateIpv4(ipv4) && ValidationUtil.validateLocalIpv4(ipv4)) {
return 0L;
}
String key = getIpKey(ipv4);
String countString = redisTemplate.opsForValue().get(key);
if (StringUtils.isBlank(countString)) {
return 0L;
}
return Long.valueOf(countString);
}
private final static String getIpKey(String ipv4){
return Constants.REDIS_PASSWORD_ERROR_COUNT_FOR_IPV4 + ipv4;
private final static String getLockIpv4Key(String ipv4){
return Constants.IPV4_LOCK + ipv4;
}
/**
......
......@@ -541,9 +541,14 @@ public class UserController implements IBaseController {
String ipv4Key = getIpKey(getIp());
if(!stringRedisTemplate.hasKey(getIpKey(getIp()))){
// 计数周期5分钟
stringRedisTemplate.opsForValue().set(ipv4Key, String.valueOf(0), 5, TimeUnit.MINUTES);
stringRedisTemplate.opsForValue().set(ipv4Key, String.valueOf(0), Constants.IPV4_COUNT_MINUTES, TimeUnit.MINUTES);
}
Long count = stringRedisTemplate.opsForValue().increment(ipv4Key, 1L);
if (count >= Constants.IPV4_LOCK_ON_COUNTS){
String lockIpv4Key = getLockIpv4Key(ipv4);
stringRedisTemplate.opsForValue().set(lockIpv4Key, Boolean.TRUE.toString(), Constants.IPV4_LOCK_MINUTES, TimeUnit.MINUTES);
LOGGER.info("Locked ip access:{}, error overstep {} times in {} minutes, do lock {} minutes", ipv4, Constants.IPV4_LOCK_ON_COUNTS, Constants.IPV4_COUNT_MINUTES, Constants.IPV4_LOCK_MINUTES);
}
stringRedisTemplate.opsForValue().increment(ipv4Key, 1L);
}
}
......@@ -551,6 +556,10 @@ public class UserController implements IBaseController {
return Constants.REDIS_PASSWORD_ERROR_COUNT_FOR_IPV4 + ipv4;
}
private final static String getLockIpv4Key(String ipv4){
return Constants.IPV4_LOCK + ipv4;
}
private boolean validatePassword(String paramPass, String targetPassword) {
return StringUtils.defaultString(targetPassword, "").equals(PasswordUtil.MD5(paramPass.toLowerCase() + pwdSalt));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment