概述
认证过程和上一篇基本一致的(shiro 学习之认证详解),进行密码比对的时候选择的比对器不一样.
- 特点:数据库不存密码明文,直接存密文.
- 注意:注册用户的时候加密密码然后存储密文和加密用的salt(俗称盐)
- 注意2:加密的算法和 shiro 配置的解密的算法要一致
项目地址:https://github.com/thecattle/spring-mvc-shiro
1. SHA-256加密
1.1 创建加密密码
首先我们有个账户,用户名为: admin, 密码为: password
然后通过下面的方法把密码加密,得到的结果:
encodedPassword(密码): qWdiGI6l8lHjpCXOSrEWOD4UX2gguGTim3hqJVe6nOc=
salt(加密用的盐):
9Se1CbOxZNFC7a9PaiKZCQ==
把它俩都存入数据库,包括盐,因为解密的时候需要它.
注意:这里的hashIterations次数,算法名字,是否 toBase64(),一定要对应 shiro.xml 解密的配置,否则肯定匹配不对
/**
* 模拟创建用户时候存入的密码和盐
* @param password
*/
private void credent(String password){
//散列随机数
String salt = new SecureRandomNumberGenerator().nextBytes().toBase64();
//散列迭代次数
int hashIterations=1024;
/*
shiro.xml 中 storedCredentialsHexEncoded=true 则需要 .toHex()
shiro.xml 中 storedCredentialsHexEncoded=false 则需要 .toBase64()
*/
String encodedPassword = new Sha256Hash(password, salt, hashIterations).toBase64();
/*
效果等同于上句代码
String encodedPassword = = new SimpleHash("SHA-256", password, salt, hashIterations);
*/
System.out.println("encodedPassword:"+encodedPassword);
System.out.println("salt:"+salt);
}
public static void main(String[] args) {
UserDaoImpl myRealm=new UserDaoImpl();
// 用户的密码为"password",现在把它加密
myRealm.credent("password");
}
那么现在我们的假数据就是这样的了
1.2 shiro.xml添加配置
由上篇文章可以知道,获取用户凭证是在 realm 中获取的,查看源码可以知道 realm 中有配置加密的入口,所以在 realm 中加入配置.如下
<!-- 配置密码匹配器 -->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 加密算法为SHA-256 -->
<property name="hashAlgorithmName" value="SHA-256"></property>
<!-- 加密迭代次数 -->
<property name="hashIterations" value="1024"></property>
<!--是否存储散列后的密码为16进制,为 true:.toHex(),为 false:.toBase64()-->
<property name="storedCredentialsHexEncoded" value="false"></property>
</bean>
</property>
最后这是这样的
1.3 realm 中返回用户凭证
shiro 解析密码的配置好了,现在配置下加解密的小桥了,现在的对象要返回这个了,带盐的
AuthenticationInfo authcInfo1 = new SimpleAuthenticationInfo(
userDao.getUserName(),
userDao.getUserPassword(),
ByteSource.Util.bytes(userDao.getSalt()),
this.getName());
整体代码这样
1.4 测试
项目跑起来看看
可以看到我们返回的用户凭证是这个
因为我们的密码匹配器设置的是这个HashedCredentialsMatcher
在认证方法中根据:
输入明文密码包装的 token
realm 中根据数据库返回的凭证 info
token 和 info 比对
得到的计算后的两个值是一样的 都是 a967..,所以匹配成功
就登录成功了
2. MD5加密
MD5同上面加密几乎一模一样,就是算法名字改下就可以了.
创建密码的时候可以用:
......
String encodedPassword = new SimpleHash(" MD5", password, salt, hashIterations).toBase64();
......
sihro.xml 中:
......
<property name="hashAlgorithmName" value="MD5"></property>
......
realm 中不变