使用Ehcache实现账号锁定功能

需求:

添加账号锁定功能,账号一段时间内多次失败则锁定账号,过一段时间后将自动解锁账号(比如锁定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);
	}
}

你可能感兴趣的:(Ehcache)