shiro 使用md5密码加密 锁定账户
此篇博客根据之前写的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密码加密 锁定账户相关推荐
- SpringBoot+Shiro实现MD5密码加密认证
一.数据库实体类 数据库实体类要包括用户ID.密码.盐值以及账户状态. username password salt status 二.自定义Realm /*** Shiro自定义Realm*/ pu ...
- 简单的MD5密码加密和解密方法
MD5的算法是不可逆的,MD5被广泛用于密码验证和消息体完整性验证. 下面的例子用到了密码加密和登陆时的解密的基本方法.当然这样很容易被暴力破解,可以做其他改进,如先设计一个足够复杂的密码,然后将他的 ...
- Java——MD5密码加密
目录 1.MD5概述 1.1.什么是MD5? 1.2.MD5加密作用 1.3.什么要使用MD5加密? 2.MD5加密流程 2.1.工具类导入 2.2.用户注册模块使用MD5 2.3.登录问题解决 1. ...
- node插件, MD5密码加密 与 解密
MD5加密插件 使用步骤1 : github搜索 MD5 步骤 二 : 2.1 安装插件: 终端输入 : npm install blueimp-md5 2.2 2.3 2.4 引入 : md5插件 ...
- 添加MD5 密码加密
编辑 /etc/grub/grub.conf 配置文件 password = 123456 password --md5 $5$H.........SS grub-crypt --md5 gru ...
- mysql8.0.19初始密码输入错误_MySQL 8.0.19支持输入3次错误密码锁定账户功能(例子)...
MySQL 8.0.19支持输入3次错误密码,锁定账户功能 例子: >CREATE USER "hechunyang"@"localhost" IDENT ...
- mysql 错误连接锁死_MySQL 8.0.19支持输入3次错误密码锁定账户功能(例子)
MySQL 8.0.19支持输入3次错误密码,锁定账户功能 例子: >CREATE USER 'hechunyang'@'localhost' IDENTIFIED BY '123456' FA ...
- Spring Security第2部分–密码加密,自定义404和403错误页面
这是Spring安全站的第二部分. 在这篇文章中,我将向您展示如何使用MD5加密密码以及自定义403和404状态代码错误页面. 如果您尚未阅读第1部分,请单击 此处 . 因为我们在这里继续第1部分项目 ...
- 常见登录密码加密方式
目录 1 常见的加密方式 1.1.可逆加密算法 1.1.1. 对称加密 1.1.2. 非对称加密 1.2.不可逆加密算法 1.3.Base64编码 2 密码加密的方式选型 2.1 MD5密码加密 2. ...
最新文章
- 语音识别数据集的处理在训练之前
- Selector-背景选择器
- 清理无用的CSS样式比较有用的几个工具
- python import 路径_Python 从相对路径下import的方法
- 项目管理其实可以简单一点——任务分工
- reverseajax(comet) socket 杂记
- esp32 怎么分配freertos 堆栈大小_嵌入式开发入门-从STM32CudeMX、FreeRtos、Proteu仿真开始...
- word 通配符_学会Word通配符,可以帮助我们批量处理好多事情
- 高等组合学笔记(十三):组合反演,反演公式
- 关于RecyclerView(一)基本使用
- 拓端tecdat|R语言风险价值:ARIMA,GARCH模型,Delta-normal法滚动估计,预测VaR(Value at Risk)和回测分析花旗公司股票时间序列数据
- Win10改Win7图片查看器|Win10新增加Windows照片查看器
- 怎么把WORD中插入的图片改为统一尺寸的,看这里,文档中图片怎么改成同样大小
- atomic java_Java中Atomic类的使用分析
- 手把手写深度学习(3)——用RNN循环神经网络自动生成歌词之理论篇
- JAVA 实现 名单按姓氏笔画为序排列
- Unity3D Android接入FCM推送
- java编译器下载_java手机版编译器下载
- 建立大学生职业成长规划4个步骤
- 创意者更新发布在即:欧美Win10份额已超Win7