东莞网站制作,网站死链是什么,做网站的功能是什么,网站前端设计软件在上一次写的文章中#xff0c;为大家说到了如何动态的从数据库加载用户、角色、权限信息#xff0c;从而实现登录验证及授权。在实际的开发过程中#xff0c;我们通常会有这样的一个需求#xff1a;当用户多次登录失败的时候#xff0c;我们应该将账户锁定#xff0c;等…在上一次写的文章中为大家说到了如何动态的从数据库加载用户、角色、权限信息从而实现登录验证及授权。在实际的开发过程中我们通常会有这样的一个需求当用户多次登录失败的时候我们应该将账户锁定等待一定的时间之后才能再次进行登录操作。一、基础知识回顾要实现多次登录失败账户锁定的功能我们需要先回顾一下基础知识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次)则将nLock0然后设置releaseTime为当前时间加上锁定周期。通过setAccountNonLocked(false)告知Spring Security该登录账户被锁定。 如果nLock小于等于1则将nLock再次存起来。 在一个合适的时机将锁定状态重置为setAccountNonLocked(true)。 这是一种非常典型的实现方式笔者向大家介绍一款非常有用的开源软件叫做ratelimitj。这个软件的功能主要是为API访问进行限流也就是说可以通过制定规则限制API接口的访问频率。那恰好登录验证接口也是API的一种啊我们正好也需要限制它在一定的时间内的访问次数。三、具体实现首先需要将ratelimitj通过maven坐标引入到我们的应用里面来。我们使用的是内存存储的版本还有redis存储的版本大家可以根据自己的应用情况选用。 dependencygroupIdes.moki.ratelimitj/groupIdartifactIdratelimitj-inmemory/artifactIdversion0.4.1/version/dependency之后通过继承SimpleUrlAuthenticationFailureHandler 实现onAuthenticationFailure方法。该实现是针对登录失败的结果的处理在我们之前的文章中已经讲过。Component
public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {AutowiredUserDetailsManager userDetailsManager;//规则定义1小时之内5次机会就触发限流行为SetRequestLimitRule 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节》 本文转载注明出处必须带连接不能只转文字字母哥博客。