添加账号锁定功能,账号一段时间内多次失败则锁定账号,过一段时间后将自动解锁账号(比如锁定5分钟),可再次进行登录。
使用缓存Ehcache来记录用户密码错误次数,若超过限定次数则锁定该用户,并记录锁定的时间,一定时间后方可解锁。
import cas.adaptors.common.cache.ehcache.EhCacheServiceImpl;
import common.log.Logger;
public class FrozenUserUtil {
private static final Logger log = Logger.getLogger(FrozenUserUtil.class);
private static EhCacheServiceImpl cacheService = new EhCacheServiceImpl();
// 默认允许出错次数
private static int MAX_FAIL_TIMES = 3;
// 默认冻结时间,单位[分钟]
private static int FROZEN_TIME = 30;
// 失败次数缓存Key
private static final String FAIL_COUNT = "fail_count";
// 开始冻结时间缓存Key
private static final String START_FROZEN_TIME = "start_frozen_time";
/**
* 设置冻结时间
* @param userName
*/
private static void setStartFrozenTime(String userName){
Long now = System.currentTimeMillis();
cacheService.put(userName, START_FROZEN_TIME, now);
}
/**
* 获取执行冻结操作的时间戳
* @param userName
* @return
*/
public static Long getStartFrozenTime(String userName){
return (Long) cacheService.get(userName, START_FROZEN_TIME);
}
/**
* 增加失败次数
* @param userName
*/
public static void failCountIncrease(String userName){
int failCount = getFailCount(userName);
if(failCount < MAX_FAIL_TIMES){
cacheService.put(userName, FAIL_COUNT, failCount + 1);
}else{
setStartFrozenTime(userName);
}
}
/**
* 获取失败次数
* @param userName
* @return
*/
private static int getFailCount(String userName){
Integer failCount = (Integer) cacheService.get(userName, FAIL_COUNT);
return failCount == null? 0:failCount;
}
/**
* 用户是否被冻结
* @param userName
* @return
*/
public static boolean isFrozen(String userName){
if(cacheService.exist(userName, START_FROZEN_TIME)){
long startFrozenTime = getStartFrozenTime(userName);
long now = System.currentTimeMillis();
if(now - startFrozenTime < FROZEN_TIME*60*1000){
return true;
}else{
cacheService.removeCache(userName);
}
}
return false;
}
/**
* 清空失败次数
* @param userName
* @return
*/
public static boolean clearFailCount(String userName){
return cacheService.remove(userName, FAIL_COUNT);
}
/**
* 获取冻结时长
* @return
*/
public static int getFrozenTime(){
return FROZEN_TIME;
}
/**
* 设置冻结时长
* @param time
*/
public static void setFrozenTime(int time){
FROZEN_TIME = time;
}
/**
* 剩余冻结时间
* @param userName 用户名
* @return
*/
public static String getLeftFrozenTime(String userName){
if(isFrozen(userName)){
int frozenTime = getFrozenTime();
Long startFrozenTime = getStartFrozenTime(userName);
Long now = System.currentTimeMillis();
Long left = (now - startFrozenTime > frozenTime*60*1000)? 0 : (startFrozenTime + frozenTime*60*1000) - now;
return String.valueOf(left/(1000*60)) ;
}
return "0";
}
}
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import cas.adaptors.common.cache.CacheService;
/**
* 缓存接口ehcahce实现类
* @author linchanglei 2016年2月2日 上午10:21:08
* @version V1.0
*/
public class EhCacheServiceImpl implements CacheService {
/**
* 序列化ID
*/
private static final long serialVersionUID = 532171767633394999L;
private CacheManager cacheManager = EhCacheManager.getEhCacheManager().getCacheManager();
private Ehcache globalCache = EhCacheManager.getEhCacheManager().getGlobalCache();
private Object cCacheLock = new Object();
@Override
public void put(Object key, Object value) {
globalCache.put(new Element(key, value));
}
@Override
public Object get(Object key) {
Element el = globalCache.get(key);
if (null != el) {
return el.getObjectValue();
}
return null;
}
@Override
public boolean exist(Object key) {
/*
* ehcache可能采用定时清除跟主动清除两种策略删掉过期键,这样存在以下问题:
* 1. 键已过期,但未触发定时事件,所以过期键未被删除
* 2. 但是isKeyInCache并不会触发主动清除策略
* 所以,实际过期isKeyInCache可能返回未过期
*/
boolean exist = globalCache.isKeyInCache(key);
if(exist){
Element e = globalCache.get(key);
if(e == null){
exist = false;
}else{
Object v = e.getObjectValue();
if(v == null){
exist = false;
}
}
}
return exist;
}
@Override
public boolean remove(Object key) {
return globalCache.remove(key);
}
@Override
public void removeAll() {
globalCache.removeAll();
}
@Override
public void put(String cacheId, Object key, Object v) {
Ehcache cache = cacheManager.getEhcache(cacheId);
if (null == cache) {
synchronized (cCacheLock) {
if (null == cache) {
cache = cacheManager.addCacheIfAbsent(cacheId);
}
}
}
Element el = new Element(key, v);
cache.put(el);
}
@Override
public Object get(String cacheId, Object key) {
Ehcache cache = cacheManager.getEhcache(cacheId);
if (null != cache) {
Element el = cache.get(key);
if(null != el){
return el.getObjectValue();
}
}
return null;
}
@Override
@SuppressWarnings("unchecked")
public List<Object> getKeys(String cacheName) {
List<Object> keys = null;
Ehcache cache = cacheManager.getCache(cacheName);
if (null != cache) {
keys = cache.getKeys();
}
if (keys == null) {
keys = new ArrayList<Object>(0);
}
return keys;
}
@Override
public List<Object> getValues(String cacheId) {
List<Object> objects = new ArrayList<Object>();
List<?> keys = getKeys(cacheId);
if (CollectionUtils.isNotEmpty(keys)) {
for (Object key : keys) {
objects.add(get(cacheId, key));
}
}
return objects;
}
@Override
public boolean exist(String cacheId, Object key) {
Ehcache cache = null;
cache = cacheManager.getEhcache(cacheId);
if (null != cache) {
boolean exist = cache.isKeyInCache(key);
if(exist){
Element e = cache.get(key);
if(e == null){
exist = false;
}else{
Object v = e.getObjectValue();
if(v == null){
exist = false;
}
}
}
return exist;
}
return false;
}
@Override
public boolean remove(String cacheId, Object key) {
boolean result = false;
Ehcache cache = null;
if (exist(cacheId, key)) {
cache = cacheManager.getCache(cacheId);
result = cache.remove(key);
}
return result;
}
/**
* 从缓存管理器删除指定缓存
* @param cacheId
*/
public void removeCache(String cacheId){
cacheManager.removeCache(cacheId);
}
}