成都创新互联网站制作重庆分公司

SpringSecurity如何实现多次登录失败后账户锁定功能-创新互联

这篇文章将为大家详细讲解有关SpringSecurity如何实现多次登录失败后账户锁定功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

创新互联公司是一家集网站建设,老河口企业网站建设,老河口品牌网站建设,网站定制,老河口网站建设报价,网络营销,网络优化,老河口网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

一、基础知识回顾

要实现多次登录失败账户锁定的功能,我们需要先回顾一下基础知识:

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存储的版本,大家可以根据自己的应用情况选用。

 es.moki.ratelimitj  ratelimitj-inmemory  0.4.1

之后通过继承SimpleUrlAuthenticationFailureHandler ,实现onAuthenticationFailure方法。该实现是针对登录失败的结果的处理,在我们之前的文章中已经讲过。

@Componentpublic class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { @Autowired UserDetailsManager userDetailsManager; //规则定义:1小时之内5次机会,就触发限流行为 Set rules =   Collections.singleton(RequestLimitRule.of(1 * 60, TimeUnit.MINUTES,5));  RequestRateLimiter limiter = new InMemorySlidingWindowRequestRateLimiter(rules); @Override public 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 的定时器轮询,当然这是最差的方案。

关于“SpringSecurity如何实现多次登录失败后账户锁定功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


标题名称:SpringSecurity如何实现多次登录失败后账户锁定功能-创新互联
文章位置:http://cxhlcq.com/article/dcjsed.html

其他资讯

在线咨询

微信咨询

电话咨询

028-86922220(工作日)

18980820575(7×24)

提交需求

返回顶部