文档章节

使用Ehcache缓存在用户输错n次账户密码之后冻结m小时的简单实现

Mr_Tank_
 Mr_Tank_
发布于 2016/07/13 15:57
字数 913
阅读 142
收藏 8

我们经常会看到有些系统,为了提高账户安全性,会在用户输入n次密码时候锁定对应的账户一段时间,这样可以避免暴力破解用户密码(说实话这样行不行我也不知道)。不知道正确的实现姿势应该是什么样的,但是我们可以利用缓存来简单实现这个功能,先来一盘代码:

0、初始化配置

为每个用户初始化保存到缓存中的key

    private int MAX_FAIL_TIMES = 3;// 默认最多允许出错次数
	private int FROZEN_TIME = 1;// 默认冻结时间,单位[小时]
	private String COUNT_KEY;// 失败次数缓存Key
	private String TIME_KEY;// 冻结时间缓存Key
	private long USERID;// 冻结的用户ID

	private String CACHE_REGION = "Account";

	public static FrozenAccountTool init(String key, long userId, int maxFailTimes, int frozenTime) {

		FrozenAccountTool frozenAccountTool = new FrozenAccountTool();

		frozenAccountTool.USERID = userId;
		frozenAccountTool.COUNT_KEY = key + "#USER#COUNT#" + frozenAccountTool.USERID;
		frozenAccountTool.TIME_KEY = key + "#USER#TIME#" + frozenAccountTool.USERID;
		frozenAccountTool.MAX_FAIL_TIMES = maxFailTimes > 0 ? maxFailTimes : frozenAccountTool.MAX_FAIL_TIMES;
		frozenAccountTool.FROZEN_TIME = frozenTime > 0 ? frozenTime : frozenAccountTool.FROZEN_TIME;
		return frozenAccountTool;
	}

1、记录验证失败次数

首先需要记录用户输错的次数,每次验证失败的时候,失败次数+1

    // 失败次数+1
	public void failCountIncrease() {
		int failCount = GetFailCount();
		_SetFailCount(failCount + 1);
	}

GetFailCount() 方法用于从缓存里面取出当前失败的次数,具体实现如下:

        // 获取失败次数
	public int GetFailCount() {
		return EhcacheUtil.get(CACHE_REGION, COUNT_KEY) == null ? 1 : (Integer) EhcacheUtil.get(CACHE_REGION, COUNT_KEY);
	}

再看一下 _SetFailCount() 方法,这里是为了在失败次数大于最大失败次数的时候设置当前时间为锁定时间,用于后面判断解锁时间是否已经到了:

        // 設置失败次数
	private void _SetFailCount(int failCount) {
		EhcacheUtil.put(CACHE_REGION, COUNT_KEY, failCount);
		if (failCount >= MAX_FAIL_TIMES) {
			SetFrozenTime();
		}
	}

2、判断账户是否被冻结

<1>.首先判断当前时间点距离被锁定的时间是否大于设定锁定的时间,大于表示已经解锁,重置锁定设置的缓存数据;注:这个要先判断,要不然锁定之后就永远无法解锁了

<2>.如果时间还没到设定锁定的时间则判断当前失败次数是否大于最大失败次数,大于表示已经被锁定

public boolean IsFrozen() {
		long frozenTimeMillis = GetFrozenTime();
		System.out.println(new Date() + ">锁定时间:" + GetFrozenTime());
		System.out.println(new Date() + ">当前错误次数:" + GetFailCount());
		if (frozenTimeMillis > 0 && (System.currentTimeMillis() - frozenTimeMillis > FROZEN_TIME * 60 * 60 * 1000)) {
			System.out.println(new Date() + ">锁定时间到,解锁账号");
			resetFrozen();
			return false;
		} else if (GetFailCount() >= MAX_FAIL_TIMES) {
			System.out.println(new Date() + ">账号已锁定..");
			return true;
		}
		System.out.println(new Date() + ">账号未锁定..");
		return false;
	}

温馨提示:以上的方法命名不符合java规范,大写是为了避免get、set、is开头的方法和javabean规范的冲突,仅供参考

** 3、如何使用 **

输入图片说明

4、测试代码

        FrozenAccountTool frozenAccountTool1 = FrozenAccountTool.init("GETCASH", 593115, 5, 1);
		for (int i = 0; i < 5; i++) {
			frozenAccountTool1.failCountIncrease();
			Thread.sleep(2000);
		}
		boolean result = true;
		while (result) {
			result = frozenAccountTool1.IsFrozen();
			Thread.sleep(5000);
		}

5、测试结果 (这里只设置锁定了0.01个小时)

输入图片说明

6、最后

我们可以看到开源中国社区的登陆也是用了同样的原理,用户输错2次密码的时候会出现验证码,输错密码次数大于限定的次数后该email账号会被锁定两个小时

(1)输错两次密码后,万恶的验证码出现了

输入图片说明

(2)输错N次之后

输入图片说明

不相信可以自己去试一下哦,似乎可以做什么坏事的样子

关于Ehcache工具类和其他代码已经托管到:https://git.oschina.net

© 著作权归作者所有

共有 人打赏支持
Mr_Tank_

Mr_Tank_

粉丝 228
博文 38
码字总数 14028
作品 0
深圳
前端工程师
私信 提问
「实用教程」登录失败超过一定次数如何锁定帐号?

前言 本教程作者是「小灯光环」,作者简介:全栈开发工程师,CSDN博客专家,CSDN论坛 Java Web/Java EE版主,热爱技术,乐于分享,在分布式Web开发/Android开发/微信小程序开发/Linux系统优化...

技术小能手
08/02
0
0
项目案例分享二:密码策略与上次交互式登录

今天有个朋友跟我聊天时提到他们公司的域用户经常会遇到被锁定的状态,而且4小时后会自动解锁,想查看AD里面是否能够统计和显示域用户登录失败次数和时间等信息。所以搭建了个小测试来解决这...

余二五
2017/11/16
0
0
网赌账号异常维护审核拖着不给出款怎么办?

网投被黑,有哪些借口:你的账户异常登录、网站维护、网站出款端口维护、账户涉嫌套利、系统自动抽查审核、网站抽查审核、账户违规下注、银行系统维护等等借口不给你出款甚至冻结你账户。不要...

V型g9335588加噢
08/27
0
0
Linux帐号管理

新增用户:useradd [option] 用户名称 -u 指定UID -g 指定初始组initial group ,就是/etc/passwd第四个字段GID对应的组 -G 此账户还可以加入的用户组 -M 强制不创建主文件夹 -m 强制创建主文...

Billy112487983
2014/04/21
0
0
当当全网冻结账户:被误判的危机?

3月23日,当当网运营高级总监梁健鹏很意外地发现,从19日晚22点到22日24点这74个小时里,当当网所有被冻结了账户的用户中只有6位致电当当网反映自己的账户异常。 另一个数据令梁健鹏更感蹊跷...

红薯
2012/03/25
2.5K
16

没有更多内容

加载失败,请刷新页面

加载更多

JAVA设计模式之模板方法模式和建造者模式

一、前期回顾 上一篇《Java 设计模式之工厂方法模式与抽象工厂模式》介绍了三种工厂模式,分别是工厂方法模式,简单工厂方法模式,抽象工厂模式,文中详细根据实际场景介绍了三种模式的定义,...

木木匠
29分钟前
2
0
C中的宏的使用(宏嵌套/宏展开/可变参数宏)

基本原则: 在展开当前宏函数时,如果形参有#或##则不进行宏参数的展开,否则先展开宏参数,再展开当前宏。 #是在定义两边加上双引号 #define _TOSTR(s) #sprintf(_TOSTR(test ABC))pr...

SamXIAO
59分钟前
2
0
SpringBoot 整合异步调用方法

1. 在 SpringBoot 主类上使用 @EnableAsync 注解,开启异步调用功能 package com.codingos.springbootdemo;import org.springframework.boot.SpringApplication;import org.springfra......

北漂的我
今天
1
0
0015-如何使用Sentry管理Hive外部表权限

1.文档编写目的 本文档主要讲述如何使用Sentry对Hive外部表权限管理,并基于以下假设: 1.操作系统版本:RedHat6.5 2.CM版本:CM 5.11.1 3.集群已启用Kerberos和Sentry 4.采用具有sudo权限的...

Hadoop实操
今天
3
0
边缘计算与数据中心的发展趋势

导读 Gartner研究表明,人工智能、物联网和5G助力下一代商业创新,由此产生大量数据,2020年前企业将使用超过75亿台联网设备。 在几乎每个方面,社会的节奏都正变得更快。我们希望客户服务问...

问题终结者
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部