Shiro限制登录尝试次数
2017-06-30 00:24
274 查看
要限制用户登录尝试次数,必然要对用户名密码验证失败做记录,Shiro中用户名密码的验证交给了CredentialsMatcher
所以在CredentialsMatcher里面检查,记录登录次数是最简单的做法。
我们用Ehcache来记录用户登录次数的计数,继承HashedCredentialsMatcher,加入缓存,在每次验证用户名密码之前先验证用户名尝试次数,如果超过5次就抛出尝试过多异常,否则验证用户名密码,验证成功把尝试次数清零,不成功则直接退出。
package org.jstudioframework.freeway.shiro.authc.credential;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 验证器,增加了登录次数校验功能
*/
public class RetryLimitCredentialsMatcher extends HashedCredentialsMatcher {
private static final Logger log = LoggerFactory.getLogger(RetryLimitCredentialsMatcher.class);
//集群中可能会导致出现验证多过5次的现象,因为AtomicInteger只能保证单节点并发
private Cache<String, AtomicInteger> lgoinRetryCache;
private int maxRetryCount = 5;
private String lgoinRetryCacheName;
public void setMaxRetryCount(int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
}
public RetryLimitCredentialsMatcher(CacheManager cacheManager,String lgoinRetryCacheName) {
this.lgoinRetryCacheName = lgoinRetryCacheName;
lgoinRetryCache = cacheManager.getCache(lgoinRetryCacheName);
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
String username = (String) token.getPrincipal();
//retry count + 1
AtomicInteger retryCount = lgoinRetryCache.get(username);
if (null == retryCount) {
retryCount = new AtomicInteger(0);
lgoinRetryCache.put(username, retryCount);
}
if (retryCount.incrementAndGet() > 5) {
log.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 data
lgoinRetryCache.remove(username);
}
return matches;
}
}
UserRealm继承AuthorizingRealm,在其父类AuthenticatingRealm的getAuthenticationInfo方法中会调用credentialsMatcher的 doCredentialsMatch 来验证用户输入用户名密码是否匹配。
Ehcache配置
<!-- 登录记录缓存 锁定10分钟 -->
<cache name="lgoinRetryCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
Spring Shiro配置
<!-- Realm实现 -->
<bean id="userRealm" class="org.jstudioframework.freeway.shiro.UserRealm">
<!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 -->
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
<!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.jstudioframework.freeway.shiro.authc.credential.RetryLimitCredentialsMatcher">
<constructor-arg index="0" ref="cacheManager"/>
<constructor-arg index="1" value="5"/>
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="1"/>
</bean>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:cache/shiro-ehcache.xml"/>
</bean>
所以在CredentialsMatcher里面检查,记录登录次数是最简单的做法。
我们用Ehcache来记录用户登录次数的计数,继承HashedCredentialsMatcher,加入缓存,在每次验证用户名密码之前先验证用户名尝试次数,如果超过5次就抛出尝试过多异常,否则验证用户名密码,验证成功把尝试次数清零,不成功则直接退出。
package org.jstudioframework.freeway.shiro.authc.credential;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 验证器,增加了登录次数校验功能
*/
public class RetryLimitCredentialsMatcher extends HashedCredentialsMatcher {
private static final Logger log = LoggerFactory.getLogger(RetryLimitCredentialsMatcher.class);
//集群中可能会导致出现验证多过5次的现象,因为AtomicInteger只能保证单节点并发
private Cache<String, AtomicInteger> lgoinRetryCache;
private int maxRetryCount = 5;
private String lgoinRetryCacheName;
public void setMaxRetryCount(int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
}
public RetryLimitCredentialsMatcher(CacheManager cacheManager,String lgoinRetryCacheName) {
this.lgoinRetryCacheName = lgoinRetryCacheName;
lgoinRetryCache = cacheManager.getCache(lgoinRetryCacheName);
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
String username = (String) token.getPrincipal();
//retry count + 1
AtomicInteger retryCount = lgoinRetryCache.get(username);
if (null == retryCount) {
retryCount = new AtomicInteger(0);
lgoinRetryCache.put(username, retryCount);
}
if (retryCount.incrementAndGet() > 5) {
log.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 data
lgoinRetryCache.remove(username);
}
return matches;
}
}
UserRealm继承AuthorizingRealm,在其父类AuthenticatingRealm的getAuthenticationInfo方法中会调用credentialsMatcher的 doCredentialsMatch 来验证用户输入用户名密码是否匹配。
Ehcache配置
<!-- 登录记录缓存 锁定10分钟 -->
<cache name="lgoinRetryCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
Spring Shiro配置
<!-- Realm实现 -->
<bean id="userRealm" class="org.jstudioframework.freeway.shiro.UserRealm">
<!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 -->
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
<!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.jstudioframework.freeway.shiro.authc.credential.RetryLimitCredentialsMatcher">
<constructor-arg index="0" ref="cacheManager"/>
<constructor-arg index="1" value="5"/>
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="1"/>
</bean>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:cache/shiro-ehcache.xml"/>
</bean>
相关文章推荐
- Shiro security限制登录尝试次数
- Spring Security笔记:登录尝试次数限制
- SpringBoot+Shiro学习之密码加密和登录失败次数限制
- Linux下设置限制登录oracle数据库及Linux操作系统的IP、尝试登录次数及长时间空闲后断开
- SpringBoot+Shiro学习之密码加密和登录失败次数限制示例
- 【Java】SpringMVC项目利用Shiro设置固定时间内密码登录重试次数限制
- redhat5.4的SSH限制登录密码尝试次数
- springboot整合shiro登录失败次数限制功能的实现代码
- SpringBoot+Shiro学习之密码加密和登录失败次数限制
- SpringBoot学习:整合shiro(验证码功能和登录次数限制功能)
- SpringBoot+Shiro学习之密码加密和登录失败次数限制
- 【Java接口】限制App登录次数
- Android锁屏尝试次数太多导致需要google账户登录问题
- Shiro限制帐号只能在一处登录
- 登录次数限制实例
- asp.net限制用户登录错误次数
- spring security实现限制登录次数功能
- Shiro - 限制并发人数登录与剔除
- Oracle用户连续登录失败次数限制如何取消
- Shiro 控制并发登录人数限制实现,登录踢出实现