此篇博客根据之前写的shiro快速配置延续的,建议不了解的可以先看看之前的博客。

springMVC中快速配置shiro

1.为了使用密码加密,我们新建一个对用户信息操作的工具类

package com.bf.planner.util;import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;import com.bf.planner.model.User;public class EncryptUtil {private static String algorithmName = "MD5"; // 加密方式private static int hashIterations = 1024; // 加密次数public static User EncryptUser(User user) {// 随机盐对象SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator();// 根据用户名以及随机生成的盐来拼接成密码盐String salt = user.getUser_name() + secureRandomNumberGenerator.nextBytes().toHex();// 获取加密后的密码String passWord = new SimpleHash(algorithmName, user.getPassword(), salt, hashIterations).toHex();user.setSalt(salt);   //设置密码盐user.setPassword(passWord);  //设置加密过后的密码return user;}}

tips:加密方式可以修改,推荐使用MD5等散列式加密方式,因为此种加密方式不可逆;密码盐我是使用用户名拼接了生成的随机盐,此处可根据需求添加私盐,或定义固定盐,推荐使用私盐加随机盐;密码盐一定要存放起来,并且不要使用ByteSource.Util.bytes()方法进行转译,因为后面我们登录时shiro需要对其进行此方法的转译。

2.用户注册或修改信息时,调用上面的工具类进行盐的设置以及密码的加密:

EncryptUtil.EncryptUser(user);

tips:此处我们传递过去的其实是user对象的引用,所以不需要接收返回值。

3.密码加密已经完成,接下来我们需要对其解密,首先在springmvc配置中配置密码解析

<!-- 数据库保存的密码是使用MD5算法加密的,所以这里需要配置一个密码匹配对象 -->  <bean id="credentialsMatcher" class="com.bf.planner.realm.MyMatcher"><constructor-arg ref="cacheManager"/>  <!-- 缓存 --><property name="hashAlgorithmName" value="MD5"></property> <!-- 加密算法的名称 --><property name="hashIterations" value="1024"></property> <!-- 配置加密的次数 --><property name="storedCredentialsHexEncoded" value="true"></property> <!-- 是否存储为16进制 --></bean><!-- 自定义Realm --><bean id="myRealm" class="com.bf.planner.realm.MyRealm"><property name="credentialsMatcher" ref="credentialsMatcher" />    <!-- 加密配置 --></bean> 

tips:上面自定义了credentialsMatcher的实现类是为了做账户锁定,如果不需要的话,只要将class引向

org.apache.shiro.authc.credential.HashedCredentialsMatcher

类,去掉缓存的配置即可。这里的配置是为了在用户登录时对用户输入的密码的加密配置,因为上面我使用的是MD5加密,加密了1024次,所以此处配置这样。

4.配置基本完成,要想使用我们还需要在MyRealm中修改:

@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String user_name = (String) token.getPrincipal();// 获取登录者的用户名User user = loginService.getUser(user_name); // 根据用户名查出数据库中所对应的用户信息if (user == null) {throw new UnknownAccountException(); // 抛出账号不存在异常}AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUser_name(), // 用户名user.getPassword(), // 密码ByteSource.Util.bytes(user.getSalt()), // 盐getName()); // realm name// 设置此用户的令牌,即设置正确的用户名与密码return authcInfo;}

tips:方法与原来的不同是在登录的验证处,我们多传递了一个盐,这是为了shiro对密码进行加密使用。

5.有的时候我们希望在用户多次输入错误密码时对其进行锁定操作,首先我们可以定义一个控制锁定密码时间的关于缓存的配置文件:

springmvc配置文件中引向我们的缓存配置文件:

<!-- 缓存管理 -->  <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"><property name="cacheManagerConfigFile" value="classpath:ehcache.xml" /></bean> 

tips:此处指向了项目下的文件。

在ehcache.xml中我们配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="shirocache" updateCheck="false"> <!-- updateCheck关闭网络获取缓存 --><diskStore path="java.io.tmpdir" />  <!-- 登录记录缓存 锁定10分钟 -->  <cache name="passwordRetryCache" eternal="false"  timeToIdleSeconds="0" timeToLiveSeconds="600" overflowToDisk="false"  maxBytesLocalHeap="10M" statistics="true">  </cache>  <!-- timeToIdleSeconds 此属性设置后,限制时间以上次访问开始 eg:设置时间为10分钟的话,我们在1分的时候账号被锁定,预定为10分时解锁.而我们在5分时再次输入密码(此时密码已被锁定,无论怎样都不会通过认证),那么解锁时间变为15分.timeToLiveSeconds 此属性设置后,限制时间以缓存创建开始eg:设置时间为10分钟的话,我们在1分的时候账号被锁定,预定为10分时解锁.而我们在5分时再次输入密码(此时密码已被锁定,无论怎样都不会通过认证),那么解锁时间还是10分.maxBytesLocalHeap用来限制缓存所能使用的堆内存的最大字节数的,如果不设置则需设置另外一个属性,否则项目会编译出错,无法允许,此处不再详写。--></ehcache>

tips:updateCheck属性默认为true,有时会抛出异常Update check failed,建议设置为false。

6.配置完之后我们需要写我们自己的MyMatcher类:

package com.bf.planner.realm;import java.util.concurrent.atomic.AtomicInteger;import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;/*** @ClassName: MyMatcher* @Description: TODO(shiro密码配置)* @author HYK* @date 2017年3月9日 下午1:18:02*/
public class MyMatcher extends HashedCredentialsMatcher {private Cache<String, AtomicInteger> passwordRetryCache; //创建缓存的对象public MyMatcher(CacheManager cacheManager) {//赋予缓存对象,此处获取的是我们在ehcache.xml文件中配置,注意getCache("")获取的是xml中的namepasswordRetryCache = cacheManager.getCache("passwordRetryCache");   }@Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {String username = (String) token.getPrincipal(); //获取用户名AtomicInteger retryCount = passwordRetryCache.get(username);    //获取用户登录的次数if (retryCount == null) {  //如果用户未登陆过retryCount = new AtomicInteger(0);   //新建一个登录次数passwordRetryCache.put(username, retryCount); //放入缓存中}if (retryCount.incrementAndGet() > 3) {  //如果用户登录次数超过三次(此处可根据需要自定义)throw new ExcessiveAttemptsException(); //抛出用户锁定异常类}boolean matches = super.doCredentialsMatch(token, info);   //判断用户是否可用,即是否为正确的账号密码if(matches){passwordRetryCache.remove(username);   //移除缓存中用户的登录次数}return matches;}}

tips:引入类为org.apache.shiro下的;用户登录时的验证方法为doCredentialsMatch(token,info),此方法中将用户输入的令牌token和正确的令牌info进行验证。有兴趣的可以查看一下它的源码。在方法中它将info中的salt(盐)获取出来,然后根据我们在配置文件中的配置对用户输入的密码进行加密处理,然后对两者进行比较,比较一致则返回true,表示登录成功,否则返回false,表示登录失败。

7.登陆时我们需要捕获用户登录的异常:

@RequestMapping("/login")@ResponseBodypublic ResultInfo login(User user) {ResultInfo resultInfo = new ResultInfo();Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(user.getUser_name(), user.getPassword());try {subject.login(token);User userInfo = loginService.getUser(user.getUser_name());subject.getSession().setAttribute("user_id", userInfo.getUser_id());resultInfo.setCode(true); // 登录成功} catch (UnknownAccountException e) {resultInfo.setCode(false);resultInfo.setMsg("用户名/密码错误");} catch (IncorrectCredentialsException e) {resultInfo.setCode(false);resultInfo.setMsg("用户名/密码错误");} catch (ExcessiveAttemptsException e) {resultInfo.setCode(false);resultInfo.setMsg("登录失败多次,账户锁定10分钟");} catch (Exception e) {e.printStackTrace();resultInfo.setCode(false);resultInfo.setMsg("其他错误");}return resultInfo;}

shiro 使用md5密码加密 锁定账户相关推荐

  1. SpringBoot+Shiro实现MD5密码加密认证

    一.数据库实体类 数据库实体类要包括用户ID.密码.盐值以及账户状态. username password salt status 二.自定义Realm /*** Shiro自定义Realm*/ pu ...

  2. 简单的MD5密码加密和解密方法

    MD5的算法是不可逆的,MD5被广泛用于密码验证和消息体完整性验证. 下面的例子用到了密码加密和登陆时的解密的基本方法.当然这样很容易被暴力破解,可以做其他改进,如先设计一个足够复杂的密码,然后将他的 ...

  3. Java——MD5密码加密

    目录 1.MD5概述 1.1.什么是MD5? 1.2.MD5加密作用 1.3.什么要使用MD5加密? 2.MD5加密流程 2.1.工具类导入 2.2.用户注册模块使用MD5 2.3.登录问题解决 1. ...

  4. node插件, MD5密码加密 与 解密

    MD5加密插件 使用步骤1 : github搜索 MD5 步骤 二 : 2.1 安装插件: 终端输入 : npm install blueimp-md5 2.2 2.3 2.4 引入 : md5插件 ...

  5. 添加MD5 密码加密

    编辑 /etc/grub/grub.conf 配置文件 password = 123456 password --md5 $5$H.........SS grub-crypt  --md5   gru ...

  6. mysql8.0.19初始密码输入错误_MySQL 8.0.19支持输入3次错误密码锁定账户功能(例子)...

    MySQL 8.0.19支持输入3次错误密码,锁定账户功能 例子: >CREATE USER "hechunyang"@"localhost" IDENT ...

  7. mysql 错误连接锁死_MySQL 8.0.19支持输入3次错误密码锁定账户功能(例子)

    MySQL 8.0.19支持输入3次错误密码,锁定账户功能 例子: >CREATE USER 'hechunyang'@'localhost' IDENTIFIED BY '123456' FA ...

  8. Spring Security第2部分–密码加密,自定义404和403错误页面

    这是Spring安全站的第二部分. 在这篇文章中,我将向您展示如何使用MD5加密密码以及自定义403和404状态代码错误页面. 如果您尚未阅读第1部分,请单击 此处 . 因为我们在这里继续第1部分项目 ...

  9. 常见登录密码加密方式

    目录 1 常见的加密方式 1.1.可逆加密算法 1.1.1. 对称加密 1.1.2. 非对称加密 1.2.不可逆加密算法 1.3.Base64编码 2 密码加密的方式选型 2.1 MD5密码加密 2. ...

最新文章

  1. 语音识别数据集的处理在训练之前
  2. Selector-背景选择器
  3. 清理无用的CSS样式比较有用的几个工具
  4. python import 路径_Python 从相对路径下import的方法
  5. 项目管理其实可以简单一点——任务分工
  6. reverseajax(comet) socket 杂记
  7. esp32 怎么分配freertos 堆栈大小_嵌入式开发入门-从STM32CudeMX、FreeRtos、Proteu仿真开始...
  8. word 通配符_学会Word通配符,可以帮助我们批量处理好多事情
  9. 高等组合学笔记(十三):组合反演,反演公式
  10. 关于RecyclerView(一)基本使用
  11. 拓端tecdat|R语言风险价值:ARIMA,GARCH模型,Delta-normal法滚动估计,预测VaR(Value at Risk)和回测分析花旗公司股票时间序列数据
  12. Win10改Win7图片查看器|Win10新增加Windows照片查看器
  13. 怎么把WORD中插入的图片改为统一尺寸的,看这里,文档中图片怎么改成同样大小
  14. atomic java_Java中Atomic类的使用分析
  15. 手把手写深度学习(3)——用RNN循环神经网络自动生成歌词之理论篇
  16. JAVA 实现 名单按姓氏笔画为序排列
  17. Unity3D Android接入FCM推送
  18. java编译器下载_java手机版编译器下载
  19. 建立大学生职业成长规划4个步骤
  20. 创意者更新发布在即:欧美Win10份额已超Win7

热门文章

  1. 虚幻4与现代C++:转移语义和右值引用
  2. 阿里云数据库ClickHouse核心技术解析
  3. HEVC解码器HM源码阅读(二)解码器中类的介绍
  4. Python 变量赋值和命名规则
  5. Android中Canvas和Paint的常用方法
  6. UV灯固化设备紫外能量值如何定期检测
  7. python pandas clip
  8. 【FFmpeg编码】了解速率控制模式(x264、x265、vpx)
  9. 最全zabbix安装部署
  10. 项目管理之如何进行项目干系人管理