【Shiro】6、Shiro实现限制密码错误次数从而限制用户登录

简介: 我们的系统非常容易遭受攻击,被人暴力破解等,我们需要对同一账户密码错误次数进行统计,达到上限后,需要在一段时间内限制该用户登录,从而有效地保护账户密码的安全
  • 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;
}

同样,我们需要在自定义授权认证的时候,传入我们的密码验证规则

目录
相关文章
|
Java 数据库 数据安全/隐私保护
用shiro框架实现注册登陆,让你快速理解shiro用法
用shiro框架实现注册登陆,让你快速理解shiro用法
475 0
用shiro框架实现注册登陆,让你快速理解shiro用法
|
安全 Java Apache
Springboot整合shiro:实现用户登录和权限验证
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。当然类型大家也可以使用spring security;因为我平时开发的项目都是中小型的,所以使用shiro对于业务来说已经够用了,那么下面是我整理的整合记录;
146 0
|
安全 数据安全/隐私保护
【Shiro】4、Shiro实现记住登录功能
用户每次在登录系统时需要重新输入账户、密码、验证码等信息,非常麻烦,于是要求加一个记住登录的功能,这对于 Shiro 来说是非常简单,下面就让我们一起来实现记住登录功能
162 0
【Shiro】4、Shiro实现记住登录功能
|
缓存 前端开发 程序员
Shiro实现多realm方案
前后端分离的背景下,在认证的实现中主要是两方面的内容,一个是用户登录获取到token,二是从请求头中拿到token并检验token的有效性和设置缓存。
Shiro实现多realm方案
|
数据库 数据安全/隐私保护
【Shiro】3、Shiro实现自定义密码验证规则
我们在使用 Shiro 实现登录的时候,我们只需要将账号、密码,Shiro 会自动判断账户、密码是否正确,那么 Shiro 怎么会知道我们的密码加密规则呢?所以我们需要自定义密码的加密规则
201 0
|
安全 Java 数据库连接
【Shiro】1、Shiro实现登录授权认证功能(上)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
299 0
|
Java 数据安全/隐私保护
【Shiro】1、Shiro实现登录授权认证功能(中)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
125 0
|
Java 数据安全/隐私保护
【Shiro】1、Shiro实现登录授权认证功能(下)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
123 0
SSM如何整合Shiro实现权限登陆案例
SSM如何整合Shiro实现权限登陆案例
67 0
|
安全 Java 数据库连接
7-SpringSecurity:获取已登录的用户信息
7-SpringSecurity:获取已登录的用户信息
445 0