热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Shiro功能拓展:登录失败重试次数限制

本文详细介绍了如何在ApacheShiro框架中实现对用户登录失败重试次数的限制,通过自定义密码匹配器来增强系统的安全性。该方法不仅能够有效防止暴力破解攻击,还能确保合法用户的账户安全。

文章目录

        • 背景介绍
        • 解决方案
        • 代码实现
        • 执行过程

本文旨在探讨如何在Apache Shiro框架中实现用户登录失败重试次数的限制,以提高系统的安全性。通过自定义密码匹配器,我们可以有效地防止恶意用户通过暴力破解的方式尝试登录系统。

背景介绍

在Web应用中,用户登录是一个常见的功能。然而,恶意用户可能会利用自动化工具频繁尝试不同的用户名和密码组合,以期找到正确的凭证。这种行为不仅消耗服务器资源,还可能危及系统安全。因此,限制用户登录失败的重试次数是一种有效的防御措施。

解决方案

为了实现这一功能,我们可以通过自定义密码匹配器来跟踪每个用户的登录尝试次数,并在达到预设的重试次数后锁定账户。具体来说,我们将继承Shiro的HashedCredentialsMatcher类,并重写其doCredentialsMatch方法。

代码实现

1. 自定义密码匹配器

首先,我们需要创建一个自定义的密码匹配器类,该类继承自HashedCredentialsMatcher,并重写doCredentialsMatch方法:

public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {
@Autowired
private IUserMapper userMapper;
private Cache passwordRetryCache;
private int retryLimitNum;

public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
passwordRetryCache = cacheManager.getCache("passwordRetryCache");
}

public void setRetryLimitNum(int retryLimitNum) {
this.retryLimitNum = retryLimitNum;
}

@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() > retryLimitNum) {
User user = userMapper.findByUserName(username);
if (user != null && 0 == user.getStatus()) {
user.setStatus(1);
userMapper.update(user);
}
System.out.println("锁定用户" + user.getUserName());
throw new LockedAccountException();
}

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

public void unlockAccount(String username) {
User user = userMapper.findByUserName(username);
if (user != null) {
user.setStatus(0);
userMapper.update(user);
passwordRetryCache.remove(username);
}
}
}

2. 配置Shiro

接下来,在ShiroConfig类中配置自定义的密码匹配器:

@Bean(name = "shiroRealm")
public MyShiroRealm getMyShiroRealm(@Qualifier("credentialsMatcherLimit") HashedCredentialsMatcher credentialsMatcher) {
MyShiroRealm shiroRealm = new MyShiroRealm();
shiroRealm.setCredentialsMatcher(credentialsMatcher);
return shiroRealm;
}

@Bean("credentialsMatcherLimit")
public RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher() {
RetryLimitHashedCredentialsMatcher matcher = new RetryLimitHashedCredentialsMatcher(getEhCacheManager());
matcher.setHashAlgorithmName("MD5");
matcher.setHashIterations(1);
matcher.setRetryLimitNum(3);
return matcher;
}

3. EHCache配置

最后,配置EHCache以存储登录失败次数的缓存:

执行过程

当用户尝试登录时,Shiro会调用自定义的doCredentialsMatch方法。首次登录时,缓存中没有该用户的记录,因此初始化重试次数为0,并将其存入缓存。如果认证成功,则清除缓存中的记录;如果认证失败,则重试次数加1。当重试次数超过预设值时,系统将锁定用户账户,并抛出LockedAccountException异常。

缓存设置为300秒(5分钟)后失效,因此用户在锁定后的5分钟内无法再次尝试登录。在控制器中捕获异常,并将异常信息返回给前端。

参考文章
Spring Boot整合Shiro - 登录失败次数限制


推荐阅读
  • Python安全实践:Web安全与SQL注入防御
    本文旨在介绍Web安全的基础知识,特别是如何使用Python和相关工具来识别和防止SQL注入攻击。通过实际案例分析,帮助读者理解SQL注入的危害,并掌握有效的防御策略。 ... [详细]
  • django项目中使用手机号登录
    本文使用聚合数据的短信接口,需要先获取到申请接口的appkey和模板id项目目录下创建ubtils文件夹,定义返回随机验证码和调取短信接口的函数function.py文件se ... [详细]
  • 利用Selenium框架解决SSO单点登录接口无法返回Token的问题
    针对接口自动化测试中遇到的SSO单点登录系统不支持通过API接口返回Token的问题,本文提供了一种解决方案,即通过UI自动化工具Selenium模拟用户登录过程,从浏览器的localStorage或sessionStorage中提取Token。 ... [详细]
  • 在现代多线程编程中,Lock接口提供的灵活性和控制力超越了传统的synchronized关键字。Lock接口不仅使锁成为一个独立的对象,还提供了更细粒度的锁定机制,例如读写锁(ReadWriteLock)。本文将探讨如何利用ReentrantReadWriteLock提高并发性能。 ... [详细]
  • 手把手教你构建简易JSON解析器
    本文将带你深入了解JSON解析器的构建过程,通过实践掌握JSON解析的基本原理。适合所有对数据解析感兴趣的开发者。 ... [详细]
  • Redis 教程01 —— 如何安装 Redis
    本文介绍了 Redis,这是一个由 Salvatore Sanfilippo 开发的键值存储系统。Redis 是一款开源且高性能的数据库,支持多种数据结构存储,并提供了丰富的功能和特性。 ... [详细]
  • 本文通过一个具体的用户管理项目,详细介绍如何使用Spring MVC框架进行开发。从用户实体类的设计到控制器的实现,再到视图层的展示,全面解析Spring MVC的核心功能与实现细节。 ... [详细]
  • 前端监控系列2 | 深入探讨JS错误监控的重要性与实践
    作者:彭莉,火山引擎APM研发工程师,专注于前端监控技术的研发。本文将深入讨论JS错误监控的必要性及其实现方法,帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 在上一期文章中,我们探讨了FastDev4Android项目中PullToRefreshListView组件的使用方法。本期将继续探讨该框架中的另一个重要组件——ACache数据缓存器,详细介绍其工作原理及如何在项目中有效利用。 ... [详细]
  • 本文详细介绍了Oracle数据库的基本架构,包括数据文件和内存结构的概念。文章重点解释了Oracle实例的组成部分,如系统全局内存区域(SGA)和后台进程,以及客户端进程与服务器进程的交互方式。此外,还探讨了SGA中的共享池、库高速缓存、锁存器及SGA缓冲区缓存等关键组件的功能和运作机制。 ... [详细]
  • 深入解析Pytest Fixture与Conftest的高级应用
    本文详细探讨了Pytest中的Fixture机制及其在conftest.py文件中的全局配置应用,涵盖Fixture的基本概念、定义、多种使用场景以及作用域等内容,适合希望深入了解Pytest测试框架的开发者。 ... [详细]
  • mybatis相关面试题 ... [详细]
  • 这个报错出现在userDao里面,sessionfactory没有注入。解决办法:spring整合Hibernate使用test测试时要把spring.xml和spring-hib ... [详细]
  • 本文详细介绍了MySQL表分区的概念、类型及其在实际应用中的实施方法,特别是针对Zabbix数据库的优化策略。 ... [详细]
  • 面对快应用开发时需要获取摘要值的需求,但官方API并未直接提供相应支持。通过探索发现,利用第三方加密库crypto-js可有效解决此问题。本文将详细介绍如何集成并使用该库来实现摘要值的获取。 ... [详细]
author-avatar
heimao
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有