登录判断_Spring Security之多次登录失败后账户锁定功能的实现
在上一次写的文章中,为大家说到了如何动态的从数据库加载用户、角色、权限信息,从而实现登录验证及授权。在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一定的时间之后才能再次进行登录操作。
一、基础知识回顾
要实现多次登录失败账户锁定的功能,我们需要先回顾一下基础知识:
- Spring Security 不需要我们自己实现登录验证逻辑,而是将用户、角色、权限信息以实现UserDetails和UserDetailsService接口的方式告知Spring Security。具体的登录验证逻辑Spring Security 会帮助我们实现。
- UserDetails接口中有一个方法叫做isAccountNonLocked()用于判断账号是否被锁定,也就是说我们应该通过该方法对应的set方法setAccountNonLocked(false)告知Spring Security该登录账户被锁定。
- 那么应该在哪里判断账号登录失败的次数并执行锁定机制呢?当然是我们之前文章给大家介绍的《自定义登录成功及失败结果处理》的AuthenticationFailureHandler。
建议您先阅读本文,如果您对本文的实现过程感到迷惑,建议您再翻看本号之前的相关内容。
二、实现多次登录失败锁定的原理
一般来说实现这个需求,我们需要针对每一个用户记录登录失败的次数nLock和锁定账户的到期时间releaseTime。具体你是把这2个信息存储在mysql、还是文件中、还是redis中等等,完全取决于你对你所处的应用架构适用性的判断。具体的实现逻辑无非就是:
- 登陆失败之后,从存储中将nLock取出来加1。
- 如果nLock大于登陆失败阈值(比如3次),则将nLock=0,然后设置releaseTime为当前时间加上锁定周期。通过setAccountNonLocked(false)告知Spring Security该登录账户被锁定。
- 如果nLock小于等于1,则将nLock再次存起来。
- 在一个合适的时机,将锁定状态重置为setAccountNonLocked(true)。
这是一种非常典型的实现方式,笔者向大家介绍一款非常有用的开源软件叫做:ratelimitj。这个软件的功能主要是为API访问进行限流,也就是说可以通过制定规则限制API接口的访问频率。那恰好登录验证接口也是API的一种啊,我们正好也需要限制它在一定的时间内的访问次数。
三、具体实现
首先需要将ratelimitj通过maven坐标引入到我们的应用里面来。我们使用的是内存存储的版本,还有redis存储的版本,大家可以根据自己的应用情况选用。
<dependency><groupId>es.moki.ratelimitj</groupId><artifactId>ratelimitj-inmemory</artifactId><version>0.4.1</version></dependency>
之后通过继承SimpleUrlAuthenticationFailureHandler ,实现onAuthenticationFailure方法。该实现是针对登录失败的结果的处理,在我们之前的文章中已经讲过。
@Component
public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {@AutowiredUserDetailsManager userDetailsManager;//规则定义:1小时之内5次机会,就触发限流行为Set<RequestLimitRule> rules = Collections.singleton(RequestLimitRule.of(1 * 60, TimeUnit.MINUTES,5)); RequestRateLimiter limiter = new InMemorySlidingWindowRequestRateLimiter(rules);@Overridepublic void onAuthenticationFailure(HttpServletRequest request,HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {String userId = //从request或request.getSession中获取登录用户名//计数器加1,并判断该用户是否已经到了触发了锁定规则boolean reachLimit = limiter.overLimitWhenIncremented(userId);if(reachLimit){ //如果触发了锁定规则,通过UserDetails告知Spring Security锁定账户user.setAccountNonLocked(false);userDetailsManager.updateUser(user);SysUser user = (SysUser) userDetailsManager.loadUserByUsername(userId);}//此处省略通过response做json或html响应}
}
- 核心实现注意看代码中的注释
- 代码中的SysUser为UserDetails的实现类,如果不知道如何实现请参考本号之前的文章
- userDetailsManager被用于管理UserDetails信息,通过改变UserDetails改变Spring Security验证行为。
四、重置锁定状态的时机
user.setAccountNonLocked(true);
重置锁定状态很简单,就是上面的代码。但是更重要的是如何选择重置锁定状态的时机。笔者能想到几种方案如下
- 下一次登陆的时候,自定义过滤器,加在Spring Boot过滤器链最前端做锁定状态重置的判断。
- 当登录账户被锁定之后,之后用户的每一次登录都会抛出LockedException。我们完全可以通过Spring Boot的全局异常捕获机制,在其中捕获LockedException,并做锁定状态的判断及重置行为。
- 写一个Spring 的定时器轮询,当然这是最差的方案。
期待您的关注
- 向您推荐博主的系列文档:《手摸手教您学习SpringBoot系列-16章97节》
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
登录判断_Spring Security之多次登录失败后账户锁定功能的实现相关推荐
- java登录失败三次一小时后再等_Spring Security实现多次登录失败后账户锁定功能...
在上一次写的文章中,为大家说到了如何动态的从数据库加载用户.角色.权限信息,从而实现登录验证及授权.在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一 ...
- mysql 用户 多次登录失败_Spring Security之多次登录失败后账户锁定功能的实现
在上一次写的文章中,为大家说到了如何动态的从数据库加载用户.角色.权限信息,从而实现登录验证及授权.在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一 ...
- java如何记住登录状态_Spring security实现记住我下次自动登录功能过程详解
一.原理分析 第一次登陆时,如果用户勾选了readme选项,登陆成功后springsecurity会生成一个cookie返回给浏览器端,浏览器下次访问时如果携带了这个cookie,springsecu ...
- 基于Spring Security的认证授权_自定义登录页面_Spring Security OAuth2.0认证授权---springcloud工作笔记127
技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们再去看自定义登录页面,之前我们使用的都是springsecurity提供的登录页面,肯定不 ...
- jwt怎么获取当前登录用户_spring oauth2如何获取当前登录用户信息
使用spring oauth2框架做授权鉴定.想获取当前用户信息怎么办? 我们知道spring oauth2是基于spring security的实现的. spring security可以通过Sec ...
- java 登录踢出_spring security 4 如何踢出用户?
项目用的是spring boot 1.3 全javaconfig 配置 目的 : 我要踢出一个登录在线的用户,踢出后,剔出的用户再次访问服务器的时候会去到登录界面, security 配置 : htt ...
- springsecurity 登录失败_Spring Security 实战干货: 401和403状态
1. 前言 最近几篇我对Spring Security中用户认证流程进行了分析,同时在分析的基础上我们实现了一个验证码登录认证的实战功能.当认证失败后交给了AuthenticationFailureH ...
- springsecurity 不允许session并行登录_Spring Security 实战干货:实现自定义退出登录...
我是 码农小胖哥.天天有编程干货分享.觉得写的不错.点个赞,转发一下,关注一下.本文为个人原创文章,转载请注明出处,非法转载抄袭将追究其责任. 1. 前言 上一篇对 Spring Security 所 ...
- java中限制多人登录的_Spring Boot + Spring Security 防止用户在多处同时登录(一个用户同时只能登录一次)及源码分析...
网上很多文章的实现方法写得比较复杂 这里介绍一个简单的方法. 实现 @Configuration @EnableWebSecurity public class SecurityConfigurati ...
最新文章
- DEAP:使用生理信号进行情绪分析的数据库(二、实验设计与主观分析)
- 清除vs2005起始页最近打开项目
- [渗透攻防] 一.从数据库原理学习网络攻防及防止SQL注入
- 如何根据灰度直方图计算标准差_如何根据电器功率计算电线的粗细?
- 怎么从运营转到前端开发_我如何在16个月内从销售人员转到前端开发人员
- MySQL 本可以用Workbench,为什么还要Navicat
- 应用时间序列案例-基于R语言
- 数据库系统工程师考试的考点是哪些?
- unity创建草地_Unity3D学习笔记(三)为地形添加花草树木
- 解读测试能力素质模型(Job Model)
- uniny 物体运动到一个点停止_unity控制运动
- 为什么计划总是坚持不下去?
- 二叉树遍历-层序-递归
- C1. Simple Polygon Embedding(几何)
- 虚幻4蓝图脚本中,函数,事件,宏的区别
- 和大家分享一款使用PHP+MYSQL搭建的OA办公管理系统源码
- 数组中用id区分拆分成多个数组,把属性拆开成多个数组
- 通过setTimeout 实现 setInterval
- java lang ClassCastException java lang Integer cannot be ca
- php 实现群发表结构,利用php怎么实现一个微信公众号无限群发功能
热门文章
- 适用于Java开发人员的Elasticsearch:Elasticsearch生态系统
- java更好的语言_Java,如果这是一个更好的世界
- 使用JBoss Fuse和OpenShift进行Cloud Native Camel骑行
- jsf集成spring_Spring和JSF集成:国际化和本地化
- Lucene查询(搜索)语法示例
- Hystrix简介–总结
- 查看您的Solr缓存大小:Eclipse Memory Analyzer
- Java 8 Friday Goodies:新的新I / O API
- Google Guava v07范例
- 使用路标的Scala和Java的Twitter REST API