瀏覽代碼

登录失败记录

master
zhao 2 年之前
父節點
當前提交
9dab229182
共有 4 個檔案被更改,包括 208 行新增0 行删除
  1. +177
    -0
      src/main/java/com/lion/config/UserLoginRecordCache.java
  2. +16
    -0
      src/main/java/com/lion/entity/LoginUserInfo.java
  3. +11
    -0
      src/main/java/com/lion/service/LoginService.java
  4. +4
    -0
      src/main/resources/config.properties

+ 177
- 0
src/main/java/com/lion/config/UserLoginRecordCache.java 查看文件

@@ -0,0 +1,177 @@
package com.lion.config;

import com.lion.entity.LoginUserInfo;
import com.lion.util.PropertiesUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

// zhao@20230427: 用户登录失败记录缓存
public final class UserLoginRecordCache
{
private static final Logger logger = LoggerFactory.getLogger(UserLoginRecordCache.class);
public static final Map<String, LoginUserInfo> cache = new HashMap<>();

private static Integer FAIL_COUNT_LIMIT;
private static Integer FAIL_LIMIT_TIME;
private static boolean inited = false;

private static void Init()
{
if(inited)
return;
FAIL_COUNT_LIMIT = ParseInt(PropertiesUtil.getProperty("USER_LOGIN.FAIL_COUNT_LIMIT"));
FAIL_LIMIT_TIME = ParseInt(PropertiesUtil.getProperty("USER_LOGIN.FAIL_LIMIT_TIME"));
inited = true;
}

private static int ParseInt(String val)
{
if(StringUtils.isEmpty(val))
return 0;
try
{
return Integer.parseInt(val);
}
catch(Exception e)
{
e.printStackTrace();
return 0;
}
}

public static String BeginUserLogin(String userId)
{
Init();
synchronized(cache) {
long time;
LoginUserInfo user;

if(FAIL_COUNT_LIMIT <= 0)
return null;

if(!cache.containsKey(userId)) // 未登录过
{
user = new LoginUserInfo();
user.setUserAccount(userId);
user.LoginFailCount(0);
user.LoginFailPunishStartTime(0);
cache.put(userId, user);
LOG("用户 {} 从未登录", userId);
return null;
}
else
user = cache.get(userId);

if(FAIL_LIMIT_TIME > 0)
{
time = System.currentTimeMillis();
long loginFailPunishStartTime = user.LoginFailPunishStartTime();
if(loginFailPunishStartTime > 0) // 锁定中
{
if(time - loginFailPunishStartTime > FAIL_LIMIT_TIME * 1000) // 过了锁定时间
{
LOG("用户 {} 登录锁定中且过了锁定时间: {} - {} > {}秒", userId, date_format(time), date_format(loginFailPunishStartTime), FAIL_LIMIT_TIME);
user.LoginFailPunishStartTime(0);
user.LoginFailCount(0);
return null;
}
else // 还在锁定时间
{
LOG("用户 {} 登录锁定中: {} - {} <= {}秒", userId, date_format(time), date_format(loginFailPunishStartTime), FAIL_LIMIT_TIME);
return "该用户登录失败已超过限制次数, 锁定登录中";
}
}
else // 未锁定
{
if(user.LoginFailCount() >= FAIL_COUNT_LIMIT) // 超过限制
{
user.LoginFailPunishStartTime(time);
LOG("用户 {} 锁定登录: {}", userId, date_format(time));
return "该用户登录失败已超过限制次数, 将锁定登录";
}
else // 还有次数
{
LOG("用户 {} 允许登录: {} < {}", userId, user.LoginFailCount(), FAIL_COUNT_LIMIT);
return null;
}
}
}
else
return null;
}
}

public static boolean EndUserLogin(String userId, boolean success)
{
synchronized(cache) {
long time;
LoginUserInfo user;

if(FAIL_COUNT_LIMIT <= 0)
return false;
user = cache.get(userId);

if(success) // 登录成功清空失败记录
{
LOG("用户 {} 登录成功", userId);
user.LoginFailPunishStartTime(0);
user.LoginFailCount(0);
return false;
}

time = System.currentTimeMillis();

user.LoginFailCount(user.LoginFailCount() + 1);
if(FAIL_LIMIT_TIME > 0)
{
if(user.LoginFailCount() >= FAIL_COUNT_LIMIT) // 超过失败次数
{
LOG("用户 {} 超出登录失败次数, 开始锁定: {} >= {}", userId, user.LoginFailCount(), FAIL_COUNT_LIMIT);
user.LoginFailPunishStartTime(time); // 锁定
return true;
}
else
{
LOG("用户 {} 登录失败剩余次数 {}", userId, FAIL_COUNT_LIMIT - user.LoginFailCount());
user.LoginFailPunishStartTime(0); // 不锁定
return false;
}
}
else
{
user.LoginFailPunishStartTime(0);
if(user.LoginFailCount() >= FAIL_COUNT_LIMIT)
user.LoginFailCount(0);
return false;
}
}
}

private static String date_format(long ts)
{
return DateFormatUtils.format(new Date(ts), "yyyy-MM-dd HH:mm:ss-SSS");
}

private static void LOG(Object obj, Object...args)
{
if(null == obj)
logger.info("NULL");
else
{
if(obj instanceof String)
{
logger.info((String)obj, args);
}
else
{
logger.info(obj.toString());
}
}
}
}

+ 16
- 0
src/main/java/com/lion/entity/LoginUserInfo.java 查看文件

@@ -17,6 +17,22 @@ public class LoginUserInfo {
private String userAccount ;//登录账号
private String roleid;
private String orgid;

// zhao@20230427
private long loginFailPunishStartTime; // 登录失败惩罚开始时间
private int loginFailCount; // 登录失败次数
public long LoginFailPunishStartTime(long...l)
{
if(null != l && l.length > 0)
loginFailPunishStartTime = l[0];
return loginFailPunishStartTime;
}
public int LoginFailCount(int...i)
{
if(null != i&& i.length > 0)
loginFailCount = i[0];
return loginFailCount;
}
public String getUserId() {
return userId;


+ 11
- 0
src/main/java/com/lion/service/LoginService.java 查看文件

@@ -21,6 +21,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.lion.config.UserLoginRecordCache;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
@@ -77,6 +78,11 @@ public class LoginService {
if(!code.equalsIgnoreCase(sessionCode)){
return Util.responseString("false","验证码错误");
}

String validateResult = UserLoginRecordCache.BeginUserLogin(userName);
if(null != validateResult)
return Util.responseString("false", validateResult);

try {
password = RasUtil.decrypt(password, private_key);
} catch (Exception e) {
@@ -91,6 +97,7 @@ public class LoginService {
String userId=list.get(0).get("id").toString();
String roleId=list.get(0).get("roleid").toString();//角色id
if(StringUtil.isEmpty(roleId)){
UserLoginRecordCache.EndUserLogin(userName, false);
return Util.responseString("false","该用户未分配角色,禁止登录");
}
String cookie=MD5Util.StringInMd5(userId+TimeUtil.getNowTimeTwo());
@@ -109,14 +116,18 @@ public class LoginService {
json.put("success","true");
json.put("message",cookie);
json.put("orgid",list.get(0).get("orgid").toString());
UserLoginRecordCache.EndUserLogin(userName, true);
return json.toString();
}else{
UserLoginRecordCache.EndUserLogin(userName, false);
return Util.responseString("false","登录失败");
}
}else{
UserLoginRecordCache.EndUserLogin(userName, false);
return Util.responseString("false","密码错误");
}
}
UserLoginRecordCache.EndUserLogin(userName, false);
return Util.responseString("false","用户名或密码不存在");
}


+ 4
- 0
src/main/resources/config.properties 查看文件

@@ -10,3 +10,7 @@ loginOut=http\://stage.huizhou.tydlxt.znxdcloud.com/api/user/logout
public_key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyAtzfkvb0EMNrlFNF1uYKYdtyYOVYUMfqWnAvRbE9XZoDlNUKqvKM8VfoNHrLBAe247iZW37+SiPqj28fztBJbEvbDOGLN0lINSyRac7v+MwSuNWGJAFE4/beM3vZz/21MDmbCReBbUSr1OBnLvzi9cPPSkaSN7trh1j/wwC559pUdhvf0MieJKwi0Q6k3NVpafszQw86r96LXfrL4GVk4OvXXIOKwFyNBgRJkWROz9L2DDJMebs4P4SJlLq+EeGRfAaOHzI8tEr/cOeiowM54z2g5BeM5xH28PpMlsx3FYXKwL+hJHs0+AQYyCt3ooPHJ4Q+7quVMOIB4Q+ATP6OQIDAQAB
#ras秘钥
private_key=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDIC3N+S9vQQw2uUU0XW5gph23Jg5VhQx+pacC9FsT1dmgOU1Qqq8ozxV+g0essEB7bjuJlbfv5KI+qPbx/O0ElsS9sM4Ys3SUg1LJFpzu/4zBK41YYkAUTj9t4ze9nP/bUwOZsJF4FtRKvU4Gcu/OL1w89KRpI3u2uHWP/DALnn2lR2G9/QyJ4krCLRDqTc1Wlp+zNDDzqv3otd+svgZWTg69dcg4rAXI0GBEmRZE7P0vYMMkx5uzg/hImUur4R4ZF8Bo4fMjy0Sv9w56KjAznjPaDkF4znEfbw+kyWzHcVhcrAv6EkezT4BBjIK3eig8cnhD7uq5Uw4gHhD4BM/o5AgMBAAECggEBAKbxB30KiXKPwscKii9H/QALSQ+2g98bSTz0SCiE6/F80vHBkKfbnW7+9AMdrAilm1rXLxA+bN1NgDcuNjRnmsJ9z3mYtgySsP1pAy0llrNYQWD9v0fYSKQ+lYWHNpcPxklege0VnHFe3yz5n1zRbTnyS4Fa39iYUfnQBTc/Kt1nrZTXqL8cHPMUHyD9sYG40JLSc5Cnr6yPRZF0DSB93tvobvqk5Ao8QiP7durVfgkKULUfNZY0ChNZ0DYcVfYqiVk2iyvtcqWLsyykjfCTuOSukniVyEDLH+PZH/8eGw5trCKfSMDY9J1cQX7oBcc+DpGI1jacvWWkicsrFE3/wlECgYEA5kGbtdhVl+wUIn3JfJKOBfa21LD6/0O9WPJqWLblF82rdlA6wfmV6rFtgpDbibT3pz1hgjKvTioXuJ4dbT0Hh4VOHIYJCQ8bcqQMfyWYPLDRzPFwaITGAwztFcZ8QoaAYqAz9FXASaBzJtCD4CmAdvFl9rug7Q88i9ZvyAsI+18CgYEA3mkg258UNDh/cXnhyDXVZ5gpEJsbSyaJK0gToFelDP7loj3vFsyOw6qYTqI8zygGxznrGxW2+QS7YebQWVdERCjwdRnbRqAIqecAJiqygCIs+9DO8PPj8733B7t9c9+FQlSSIv2DXk7ZwTWzpHa6XmkCCBd1Mr2gYE4dgaiPiWcCgYA0/9MEh1gkUP3NdqCjIOS58LDiwh30FbaGu73Iz8hpsziNUihEL9vXGqH3VLqDtvjuMM2590qstjmhkBt74nlSM1fobt2zjRunRqVtusyQ465W+xgBptYhK5+CzJ4bffQdP3zV98r754e53nMMbOEZ/7SVl1iSWFh6Y5B1Pj0CBwKBgBgbzTQBSm9esHHchFzvePKBy/HA3nSG+Nd4OKho17tQ5hNwIzqVceRD2b6sV2sdK57s6E9HS04y9RznqC4HB59b0LTg2KQPNOE16Q46Ep9RFQ820zfLOCpzrRNpf2/QCuHlyPGCCXtvkKsg5xgsxob1WwMFh+64H2pRDWHAo86BAoGAfyD3Is5t6i8AmL/0W2Iq6qgT8C6ArmkiMZ4eXYX2Ko1MtjjAsRAcNJooC9/fTsRgNRe1EtR7a4jBzBvOISET9VAyhbGvLVNjFXdIn1oF4EqHlBXmk/D/G48+KOx8g4Z7bwzYL3cLPydhbGDoO2MHIPJlS07j8xGAgoVQGBTnWfw=
# ??????????????, 0???
USER_LOGIN.FAIL_COUNT_LIMIT=5
# ??????????????????, 0???
USER_LOGIN.FAIL_LIMIT_TIME=90

Loading…
取消
儲存