JFinal与JFinalShiroPlugin整合,自定义凭证匹配器实现登录次数限制,ehcache缓存无效,求解答

以下是部分代码:

  • shiro.ini配置

##加密方式
credentialsMatcher = com.dreamliu.shiro.credentialsmatcher.RetryLimitCredentialsMatcher
credentialsMatcher.hashAlgorithmName = md5
credentialsMatcher.hashIterations = 2
credentialsMatcher.storedCredentialsHexEncoded = true
##缓存实现
shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
shiroCacheManager.cacheManagerConfigFile = classpath:ehcache-shiro.xml
securityManager.cacheManager = $shiroCacheManager

自定义凭证匹配器

public class RetryLimitCredentialsMatcher extends HashedCredentialsMatcher {

	// 允许最大登录错误次数
	private int maxRetryNum = 5;
	//
	private Cache<String, AtomicInteger> passwordRetryCache;

	public RetryLimitCredentialsMatcher() {
		super();
		CacheManager cacheManager = new EhCacheManager();
		passwordRetryCache = cacheManager.getCache("passwordRetryCache");
	}

	@Override
	public boolean doCredentialsMatch(AuthenticationToken token,
			AuthenticationInfo info) {
		String username = (String) token.getPrincipal();
		// retry count + 1
		AtomicInteger retryCount = passwordRetryCache.get(username);
		if (retryCount == null) {
			retryCount = new AtomicInteger(0);
			passwordRetryCache.put(username, retryCount);
		}
		if (retryCount.incrementAndGet() > maxRetryNum) {
			// if retry count > 5 throw
			LogKit.warn("username: " + username
					+ " tried to login more than 5 times in period");
			throw new ExcessiveAttemptsException("username: " + username
					+ " tried to login more than 5 times in period");
		}

		boolean matches = super.doCredentialsMatch(token, info);
		if (matches) {
			// clear retry count
			passwordRetryCache.remove(username);
		}
		return matches;
	}

ehcache-shiro.xml配置

<!-- 登录记录缓存 锁定10分钟 -->  
<cache name="passwordRetryCache"
           eternal="false"
           timeToIdleSeconds="600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

问题描述:

        连续错误登录5次后,第6次错误登录确实提示“锁定10分钟”的信息,继续错误登录,依然提示;但闲置一段时间后(没到10分钟),再去登录,提示变成了“用户名或密码错误”,也就是说,还没到10分钟,缓存似乎不起作用了?

评论区

JFinal

2018-12-26 17:50

这个只能单步调试定位原因

由于你这个问题十分明显,所以一次调试就可以知道原因了

JFinal

2018-12-26 17:51

例如你说的,没到 10 分钟提示就变成了 “用户名或密码错误”,这个一调试就出来了, 看程序走了哪个分支,但是你去猜原因的话是很难的

Das Leben

2018-12-26 18:00

@JFinal 波总,我debug下,发现前5次retryCount由0-4,第6次变成5,满足>5的调节,抛出ExcessiveAttemptsException异常,但闲置不到10分钟,再登录的时候retryCount变成null了,所以就提示“用户名或密码错误”

热门反馈

扫码入社