这次讲讲如何限制用户登录尝试次数,防止坏人多次尝试,恶意暴力破解密码的情况出现,要限制用户登录尝试次数,必然要对用户名密码验证失败做记录,Shiro中用户名密码的验证交给了CredentialsMatcher所以在CredentialsMatcher里面检查,记录登录次数是最简单的做法。当登录失败次数达到限制,修改数据库中的状态字段,并返回前台错误信息。
,因为之前的博客都是用的明文,这里就不对密码进行加密了,如果有需要加密,将自定义密码比较器从SimpleCredentialsMatcher改为HashedCredentialsMatcher然后将对应的配置项打开就可以。
非常抱歉,因为我之前整合的时候,只是注意功能,而没有注意细节,导致在登录失败之后,再次转发到发布方法/登录也就是真正的登录方法,导致再次登录,然后导致下面密码错误3次之后就锁定我设置的是5次。
所以将shiroConfig中的值改为shiroFilterFactoryBean.setLoginUrl(“/?;具体参考源代码。
,另外还需要将自定义ShiroRealm中密码对比注销掉,将密码对比交给底层的密码比较器才可以锁定用户,否则将永远报密码错误,具体代码如下:
,修改登录方法改为登录之后,重定向到/指数
自定义RetryLimitHashedCredentialsMatcher继承SimpleCredentialsMatcher
包com.springboot.test.shiro.config.shiro; 进口java.util.concurrent.atomic.AtomicInteger; 进口com.springboot.test.shiro.modules.user.dao.UserMapper; 进口com.springboot.test.shiro.modules.user.dao.entity.User; 进口org.apache.log4j.Logger; 进口org.apache.shiro.authc.AuthenticationInfo; 进口org.apache.shiro.authc.AuthenticationToken; 进口org.apache.shiro.authc.LockedAccountException; 进口org.apache.shiro.authc.credential.SimpleCredentialsMatcher; 进口org.apache.shiro.cache.Cache; 进口org.apache.shiro.cache.CacheManager; 进口org.springframework.beans.factory.annotation.Autowired;/* * * @author: WangSaiChao * @date: 2018/5/25 * @description:登陆次数限制 */公开课RetryLimitHashedCredentialsMatcher延伸SimpleCredentialsMatcher { 私有静态最终日志记录器=Logger.getLogger (RetryLimitHashedCredentialsMatcher.class); @ autowired 私人usermap usermap; 私人Cache<字符串,AtomicInteger>passwordRetryCache; 公共RetryLimitHashedCredentialsMatcher (CacheManager CacheManager) { passwordRetryCache=cacheManager.getCache (“passwordRetryCache”); } @Override 公共布尔doCredentialsMatch (AuthenticationToken令牌,AuthenticationInfo信息){//获取用户名 字符串的用户名=(字符串)token.getPrincipal ();//获取用户登录次数 AtomicInteger retryCount=passwordRetryCache.get(用户名); 如果(retryCount==null) {//如果用户没有登陆过,登陆次数加1并放入缓存 retryCount=new AtomicInteger (0); passwordRetryCache。把(用户名、retryCount); } 如果(retryCount.incrementAndGet()在5){//如果用户登陆失败次数大于5次抛出锁定用户异常并修改数据库字段 用户用户=userMapper.findByUserName(用户名); (如果用户!=零,,“0”.equals (user.getState ())) {//数据库字段默认为0就是正常状态所以要改为1//修改数据库的状态字段为锁定 user.setState (" 1 "); userMapper.update(用户); } logger.info(“锁定用户”+ user.getUsername ());//抛出用户锁定异常 把新LockedAccountException (); }//判断用户账号和密码是否正确 布尔匹配=超级。doCredentialsMatch(令牌,信息); 如果(匹配){//如果正确,从缓存中将用户登录计数清除 passwordRetryCache.remove(用户名); } 返回匹配; }/* * *根据用户名解锁用户 * @param用户名 * @return */公共空间unlockAccount(字符串的用户名){ 用户用户=userMapper.findByUserName(用户名); 如果(用户!=null) {//修改数据库的状态字段为锁定 user.setState (“0”); userMapper.update(用户); passwordRetryCache.remove(用户名); } } }
在shiroConfig中配置该bean
/* * *配置密码比较器 * @return */@ bean (“credentialsMatcher”) 公共RetryLimitHashedCredentialsMatcher RetryLimitHashedCredentialsMatcher () { RetryLimitHashedCredentialsMatcher RetryLimitHashedCredentialsMatcher=new RetryLimitHashedCredentialsMatcher (ehCacheManager ());//如果密码加密,可以打开下面配置//加密算法的名称//retryLimitHashedCredentialsMatcher.setHashAlgorithmName (MD5);//配置加密的次数//retryLimitHashedCredentialsMatcher.setHashIterations (1024);//是否存储为16进制//retryLimitHashedCredentialsMatcher.setStoredCredentialsHexEncoded(真正的); 返回retryLimitHashedCredentialsMatcher; }springboot整合shiro登录失败次数限制功能的实现代码