栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot整合shiro登录失败次数限制功能的实现代码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot整合shiro登录失败次数限制功能的实现代码

这次讲讲如何限制用户登录尝试次数,防止坏人多次尝试,恶意暴力破解密码的情况出现,要限制用户登录尝试次数,必然要对用户名密码验证失败做记录,Shiro中用户名密码的验证交给了CredentialsMatcher 所以在CredentialsMatcher里面检查,记录登录次数是最简单的做法。当登录失败次数达到限制,修改数据库中的状态字段,并返回前台错误信息。
 因为之前的博客都是用的明文,这里就不对密码进行加密了,如果有需要加密,将自定义密码比较器从SimpleCredentialsMatcher改为HashedCredentialsMatcher 然后将对应的配置项打开就可以。

说在前面

非常抱歉,因为我之前整合的时候,只是注意功能,而没有注意细节,导致在登录失败之后,再次转发到 post方法/login 也就是真正的登录方法,导致 再次登录,然后导致下面密码错误3次之后 就 锁定 我设置的是5次.
所以将shiroConfig中的值改为shiroFilterFactoryBean.setLoginUrl("/");具体参考源代码。

 另外 还需要将 自定义ShiroRealm 中 密码对比注销掉, 将密码对比 交给 底层的 密码比较器才可以 锁定用户,否则将 永远报密码错误。,具体代码 如下:

 

 修改登录方法改为登录之后,重定向到/index

限制登录次数

自定义RetryLimitHashedCredentialsMatcher继承SimpleCredentialsMatcher

package com.springboot.test.shiro.config.shiro;
import java.util.concurrent.atomic.AtomicInteger;
import com.springboot.test.shiro.modules.user.dao.UserMapper;
import com.springboot.test.shiro.modules.user.dao.entity.User;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.springframework.beans.factory.annotation.Autowired;

public class RetryLimitHashedCredentialsMatcher extends SimpleCredentialsMatcher {
 private static final Logger logger = Logger.getLogger(RetryLimitHashedCredentialsMatcher.class);
 @Autowired
 private UserMapper userMapper;
 private Cache passwordRetryCache;
 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) {
   //如果用户没有登陆过,登陆次数加1 并放入缓存
   retryCount = new AtomicInteger(0);
   passwordRetryCache.put(username, retryCount);
  }
  if (retryCount.incrementAndGet() > 5) {
   //如果用户登陆失败次数大于5次 抛出锁定用户异常 并修改数据库字段
   User user = userMapper.findByUserName(username);
   if (user != null && "0".equals(user.getState())){
    //数据库字段 默认为 0 就是正常状态 所以 要改为1
    //修改数据库的状态字段为锁定
    user.setState("1");
    userMapper.update(user);
   }
   logger.info("锁定用户" + 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.setState("0");
   userMapper.update(user);
   passwordRetryCache.remove(username);
  }
 }
}

在shiroConfig中配置该bean


@Bean("credentialsMatcher")
public RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher(){
 RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher = new RetryLimitHashedCredentialsMatcher(ehCacheManager());

 //如果密码加密,可以打开下面配置
 //加密算法的名称
 //retryLimitHashedCredentialsMatcher.setHashAlgorithmName("MD5");
 //配置加密的次数
 //retryLimitHashedCredentialsMatcher.setHashIterations(1024);
 //是否存储为16进制
 //retryLimitHashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);

 return retryLimitHashedCredentialsMatcher;
}

在shiroRealm中配置密码比较器


@Bean
public ShiroRealm shiroRealm(){
 ShiroRealm shiroRealm = new ShiroRealm();
 ......
 //配置自定义密码比较器
 shiroRealm.setCredentialsMatcher(retryLimitHashedCredentialsMatcher());
 return shiroRealm;
}

在ehcache-shiro.xml添加缓存项



在LoginController中添加解除admin用户限制方法


@RequestMapping("/unlockAccount")
public String unlockAccount(Model model){
 model.addAttribute("msg","用户解锁成功");

 retryLimitHashedCredentialsMatcher.unlockAccount("admin");

 return "login";
}

注意:为了方便测试,记得将 unlockAccount 权限改为 任何人可访问。

在login.html页面 添加 解锁admin用户的按钮

解锁admin用户

测试结果


总结

以上所述是小编给大家介绍的springboot整合shiro-登录失败次数限制,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/140082.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号