概述
認(rèn)證過程和上一篇基本一致的(shiro 學(xué)習(xí)之認(rèn)證詳解),進(jìn)行密碼比對(duì)的時(shí)候選擇的比對(duì)器不一樣.
- 特點(diǎn):數(shù)據(jù)庫(kù)不存密碼明文,直接存密文.
- 注意:注冊(cè)用戶的時(shí)候加密密碼然后存儲(chǔ)密文和加密用的salt(俗稱鹽)
- 注意2:加密的算法和 shiro 配置的解密的算法要一致
項(xiàng)目地址:https://github.com/thecattle/spring-mvc-shiro
1. SHA-256加密
1.1 創(chuàng)建加密密碼
首先我們有個(gè)賬戶,用戶名為: admin, 密碼為: password
然后通過下面的方法把密碼加密,得到的結(jié)果:
encodedPassword(密碼): qWdiGI6l8lHjpCXOSrEWOD4UX2gguGTim3hqJVe6nOc=
salt(加密用的鹽):
9Se1CbOxZNFC7a9PaiKZCQ==
把它倆都存入數(shù)據(jù)庫(kù),包括鹽,因?yàn)榻饷艿臅r(shí)候需要它.
注意:這里的hashIterations次數(shù),算法名字,是否 toBase64(),一定要對(duì)應(yīng) shiro.xml 解密的配置,否則肯定匹配不對(duì)
/**
* 模擬創(chuàng)建用戶時(shí)候存入的密碼和鹽
* @param password
*/
private void credent(String password){
//散列隨機(jī)數(shù)
String salt = new SecureRandomNumberGenerator().nextBytes().toBase64();
//散列迭代次數(shù)
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",現(xiàn)在把它加密
myRealm.credent("password");
}
那么現(xiàn)在我們的假數(shù)據(jù)就是這樣的了
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>
<!-- 加密迭代次數(shù) -->
<property name="hashIterations" value="1024"></property>
<!--是否存儲(chǔ)散列后的密碼為16進(jìn)制逆巍,為 true:.toHex(),為 false:.toBase64()-->
<property name="storedCredentialsHexEncoded" value="false"></property>
</bean>
</property>
最后這是這樣的
1.3 realm 中返回用戶憑證
shiro 解析密碼的配置好了,現(xiàn)在配置下加解密的小橋了,現(xiàn)在的對(duì)象要返回這個(gè)了,帶鹽的
AuthenticationInfo authcInfo1 = new SimpleAuthenticationInfo(
userDao.getUserName(),
userDao.getUserPassword(),
ByteSource.Util.bytes(userDao.getSalt()),
this.getName());
整體代碼這樣
1.4 測(cè)試
項(xiàng)目跑起來看看
可以看到我們返回的用戶憑證是這個(gè)
因?yàn)槲覀兊拿艽a匹配器設(shè)置的是這個(gè)HashedCredentialsMatcher
在認(rèn)證方法中根據(jù):
輸入明文密碼包裝的 token
realm 中根據(jù)數(shù)據(jù)庫(kù)返回的憑證 info
token 和 info 比對(duì)
得到的計(jì)算后的兩個(gè)值是一樣的 都是 a967..,所以匹配成功
就登錄成功了
2. MD5加密
MD5同上面加密幾乎一模一樣,就是算法名字改下就可以了.
創(chuàng)建密碼的時(shí)候可以用:
......
String encodedPassword = new SimpleHash(" MD5", password, salt, hashIterations).toBase64();
......
sihro.xml 中:
......
<property name="hashAlgorithmName" value="MD5"></property>
......
realm 中不變