一、session
public Object login(User user,HttpSession session) throws Exception { String username = user.getUsername(); String password = user.getPassword(); if(!checkLock(session, username)) { throw new CustomException(StatusCode.ERROR_CODE,"该账号已被锁定"); } if (StringUtils.isEmpty(username)||StringUtils.isEmpty(password)) { throw new CustomException(StatusCode.ERROR_CODE, "用户名和密码不能为空!"); } User u = getByUsername(username); if (u == null) { throw new CustomException(StatusCode.ERROR_CODE, "用户名不存在!"); } if(!MD5Util.checkpassword(password, u.getPassword())) { //新增登录失败记录 addFailNum(session, username); throw new CustomException(StatusCode.ERROR_CODE, "用户名或密码错误!"); } //清空登录失败记录 cleanFailNum(session, username); }
/** * 校验用户登录失败次数 * @param session * @param username * @return */ public boolean checkLock(HttpSession session,String username) { Object o = session.getServletContext().getAttribute(username); if(o==null) { return true; } HashMap<String,Object> map = (HashMap<String, Object>) o; int num = (int) map.get("num"); Date date = (Date) map.get("lastDate"); long timeDifference = ((new Date().getTime()-date.getTime())/60/1000); if(num>=3&&timeDifference<30) { return false; } return true; } /** * 新增用户登录失败次数 * @param session * @param username */ public void addFailNum(HttpSession session, String username) { Object o = session.getServletContext().getAttribute(username); HashMap<String,Object> map = null; int num= 0; if(o==null) { map = new HashMap<String,Object>(); }else { map = (HashMap<String, Object>) o; num = (int) map.get("num"); Date date = (Date) map.get("lastDate"); long timeDifference = ((new Date().getTime()-date.getTime())/60/1000); if(timeDifference>=30) { num=0; } } map.put("num", num+1); map.put("lastDate", new Date()); session.getServletContext().setAttribute(username, map); } /** * 清理用户登录失败的记录 * @param session * @param username */ public void cleanFailNum(HttpSession session, String username) { session.getServletContext().removeAttribute(username); }
二、map
/** * 移出非安全登录记录 * * @param index_ */ private void removeJPTLoginSecurity(String ip, String loginKey) { // 移出非安全记录索引 nonSecurityIndex.remove(ip); nonSecurityIndex.remove(loginKey); } /** * 如果超出非安全登录记录的保存范围,则自动删除以往数据,非安全记录范围个数为30个 */ private void outJPTLoginSecurity() { if (null != nonSecurityIndex && nonSecurityIndex.keySet().size() > 30) { nonSecurityIndex.clear(); } } private JPTLoginSecurity getSecurity(String ip, String loginKey) { JPTLoginSecurity security = null; if (null == nonSecurityIndex){ return null; } security = nonSecurityIndex.get(ip); if (null == security){ security = nonSecurityIndex.get(loginKey); } return security; } /** * 获取登录账户是否被锁定 * * @param index_ * @return * @throws Exception */ private boolean isLocked(String ip, String loginKey) throws Exception { JPTLoginSecurity security = getSecurity(ip, loginKey); if (null == security){ return false; } Calendar c = Calendar.getInstance(); Calendar now = Calendar.getInstance(); c.setTime(security.getLastLoginTime()); if (0 < security.getLocked()) {// 当前账号被锁定 if (c.before(now)) {// 超过锁定时间,可再次登录 security.setLocked(0);// 对账号进行解锁 security.setLoginCount(1); security.setLastLoginTime(new Date()); return false; } return true;// 锁定用户未超过锁定时间,不可登录 } return false; } /** * 验证用户是否安全,一次连续尝试只能尝试10次(默认5分钟为一次连续尝试) 如果用户在一次尝试中连续尝试了10次以上则帐户被锁 * * @param ip * ip地址 * @param loginKey * 用户登录方式 * @param index_ * 非安全记录索引 * @return * @throws Exception */ private boolean isSafe(String ip, String loginKey) throws Exception { // 思路: // 1.如果索引存在,则直接计算 // 2.如果索引不存在,调用outJPTLoginSecurity()计算是否超出记录范围,如果未超出则根据ip和loginKey生成非安全记录 outJPTLoginSecurity(); JPTLoginSecurity security = null; if (null == nonSecurityIndex) { //nonSecurityIndex = new HashMap<String, JPTLoginSecurity>(); nonSecurityIndex = new ConcurrentHashMap<String, JPTLoginSecurity>(); } else { security = getSecurity(ip, loginKey); } // TODO 判断用户是否安全 if (null == security) { security = new JPTLoginSecurity(); security.setLoginKey(loginKey); nonSecurityIndex.put(ip, security); nonSecurityIndex.put(loginKey, security); } Calendar c = Calendar.getInstance(); Calendar now = Calendar.getInstance(); c.setTime(security.getLastLoginTime()); c.add(Calendar.MINUTE, 5); if (c.after(now)) { // 说明当前是连续登录 if (security.getLoginCount() < 10) { security.setLoginCount(security.getLoginCount() + 1); return true; } else { security.setLocked(1); c = Calendar.getInstance(); c.setTime(new Date()); c.add(Calendar.MINUTE, 10); security.setLastLoginTime(c.getTime()); return false; } } else { security.setLoginCount(1); security.setLastLoginTime(new Date()); return true; } }
private static Map<String, JPTLoginSecurity> nonSecurityIndex = null;
public class JPTLoginSecurity implements Serializable{ private String ip; // IP地址 private String loginKey; //登录人账号或dn private int locked=0; //是否锁,0为未锁,1为锁 private Date lastLoginTime=new Date(); //最后登录时间 private int loginCount=0; //登录次数,10次为上限 public JPTLoginSecurity() { super(); } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getLoginKey() { return loginKey; } public void setLoginKey(String loginKey) { this.loginKey = loginKey; } public int getLocked() { return locked; } public void setLocked(int locked) { this.locked = locked; } public Date getLastLoginTime() { return lastLoginTime; } public void setLastLoginTime(Date lastLoginTime) { this.lastLoginTime = lastLoginTime; } public int getLoginCount() { return loginCount; } public void setLoginCount(int loginCount) { this.loginCount = loginCount; } }
if (nonSecurityIndex!=null&&isLocked(ip, loginKey)){ //账户被锁定 result = "-9"; //return SUCCESS; }
if (!isSafe(ip, loginKey)) { result = "-9"; //增加用户登录失败次数控制 五分钟内用户只能连续尝试登录10次,超过账号将锁定10分钟 //return SUCCESS; }
// 登陆成功后如果存在非安全登录信息,则登录成功移除 if (null != nonSecurityIndex){ removeJPTLoginSecurity(ip, loginKey); }