概述
我们的系统非常容易遭受攻击,被人暴力破解等,我们需要对同一账户密码错误次数进行统计,达到上限后,需要在一段时间内限制该用户登录,从而有效地保护账户密码的安全
- 1、重试限制散列凭据匹配器
package com.asurplus.common.shiro;
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 java.util.concurrent.atomic.AtomicInteger;
/**
* 重试限制散列凭据匹配器
* 输错5次密码锁定半小时,shiro-ehcache.xml配置
*/
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {
/**
* 错误次数
*/
private int incrementAndGet = 5;
/**
* 缓存对象
*/
private Cache<String, AtomicInteger> passwordRetryCache;
public void setIncrementAndGet(int incrementAndGet) {
this.incrementAndGet = incrementAndGet;
}
public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
passwordRetryCache = cacheManager.getCache("passwordRetryCache");
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
String username = (String) token.getPrincipal();
AtomicInteger retryCount = passwordRetryCache.get(username);
if (retryCount == null) {
retryCount = new AtomicInteger(0);
passwordRetryCache.put(username, retryCount);
}
if (retryCount.incrementAndGet() > incrementAndGet) {
throw new ExcessiveAttemptsException();
}
boolean matches = super.doCredentialsMatch(token, info);
if (matches) {
passwordRetryCache.remove(username);
}
return matches;
}
}
通过上一篇【Shiro】五、Shiro整合Ehcache进行热点数据缓存博客,我们得到了 EhCacheManager 对象,这里我们刚好就用到了它,我们需要在 shiro-ehcache.xml 配置文件中,加一个存储对象,如下:
<!-- 密码校验错误,锁定30分钟 -->
<cache name="passwordRetryCache" maxElementsInMemory="10000" maxElementsOnDisk="100000" eternal="false" timeToIdleSeconds="900" timeToLiveSeconds="900" overflowToDisk="false" diskPersistent="false" />
当密码错误次数大于我们设定的上限后,会抛出 ExcessiveAttemptsException 异常,我们在登录方法中可以捕获该异常,从而返回给客户端提示消息
- 2、自定义密码匹配器
/**
* 凭证匹配器
* 执行login(token)后由securityManager调用,用于计算密码加密后的密文
*
* @return
*/
@Bean
public RetryLimitHashedCredentialsMatcher hashedCredentialsMatcher() {
RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher = new RetryLimitHashedCredentialsMatcher(ehCacheManager());
// 设置散列算法
retryLimitHashedCredentialsMatcher.setHashAlgorithmName("md5");
// 设置散列计算次数,相当于md5(md5(""))
retryLimitHashedCredentialsMatcher.setHashIterations(6);
// storedCredentialsHexEncoded默认是true,此时用的是密码加密用的是Hex编码;false时用Base64编码
retryLimitHashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
// 错误限制次数,5次
retryLimitHashedCredentialsMatcher.setIncrementAndGet(5);
return retryLimitHashedCredentialsMatcher;
}
之前的博客【Shiro】三、Shiro实现自定义密码验证规则,我们已经知道如何自定义密码验证规则,这次我们需要改写它
我们使用到了 RetryLimitHashedCredentialsMatcher 对象,它继承了 HashedCredentialsMatcher 对象,只是在 doCredentialsMatch (文档标识符匹配)方法中我们实现了自己的业务逻辑
- 3、自定义认证授权规则
/**
* 自定义认证授权规则
*/
@Bean
public LoginRelam loginRelam() {
// 登录认证规则
LoginRelam loginRelam = new LoginRelam();
// 自定义加密规则
loginRelam.setCredentialsMatcher(hashedCredentialsMatcher());
return loginRelam;
}
同样,我们需要在自定义授权认证的时候,传入我们的密码验证规则
如您在阅读中发现不足,欢迎留言!!!
最后
以上就是生动绿草为你收集整理的【Shiro】6、Shiro实现限制密码错误次数从而限制用户登录的全部内容,希望文章能够帮你解决【Shiro】6、Shiro实现限制密码错误次数从而限制用户登录所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复