shiro教程(3)-shiro授權(quán)
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括蓮花網(wǎng)站建設(shè)、蓮花網(wǎng)站制作、蓮花網(wǎng)頁(yè)制作以及蓮花網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,蓮花網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到蓮花省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
Shiro是apache旗下一個(gè)開(kāi)源框架,它將軟件系統(tǒng)的安全認(rèn)證相關(guān)的功能抽取出來(lái),實(shí)現(xiàn)用戶身份認(rèn)證,權(quán)限授權(quán)、加密、會(huì)話管理等功能,組成了一個(gè)通用的安全認(rèn)證框架。
既然shiro將安全認(rèn)證相關(guān)的功能抽取出來(lái)組成一個(gè)框架,使用shiro就可以非??焖俚耐瓿烧J(rèn)證、授權(quán)等功能的開(kāi)發(fā),降低系統(tǒng)成本。
shiro使用廣泛,shiro可以運(yùn)行在web應(yīng)用,非web應(yīng)用,集群分布式應(yīng)用中越來(lái)越多的用戶開(kāi)始使用shiro。
Java領(lǐng)域中spring security(原名Acegi)也是一個(gè)開(kāi)源的權(quán)限管理框架,但是spring security依賴spring運(yùn)行,而shiro就相對(duì)獨(dú)立,最主要是因?yàn)閟hiro使用簡(jiǎn)單、靈活,所以現(xiàn)在越來(lái)越多的用戶選擇shiro。
最基礎(chǔ)的是Realm接口,CachingRealm負(fù)責(zé)緩存處理,AuthenticationRealm負(fù)責(zé)認(rèn)證,AuthorizingRealm負(fù)責(zé)授權(quán),通常自定義的realm繼承AuthorizingRealm。
[java]view plain copy print?
public class CustomRealm1 extends AuthorizingRealm {
@Override
public String getName() {
return "customRealm1";
}
//支持UsernamePasswordToken
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
//認(rèn)證
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
//從token中 獲取用戶身份信息
String username = (String) token.getPrincipal();
//拿username從數(shù)據(jù)庫(kù)中查詢
//....
//如果查詢不到則返回null
if(!username.equals("zhang")){//這里模擬查詢不到
return null;
}
//獲取從數(shù)據(jù)庫(kù)查詢出來(lái)的用戶密碼
String password = "123";//這里使用靜態(tài)數(shù)據(jù)模擬。。
//返回認(rèn)證信息由父類AuthenticatingRealm進(jìn)行認(rèn)證
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
username, password, getName());
return simpleAuthenticationInfo;
}
//授權(quán)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
}
}
[html]view plain copy print?
[main]
#自定義 realm
customRealm=com.sihai.shiro.authentication.realm.CustomRealm1
#將realm設(shè)置到securityManager
securityManager.realms=$customRealm
測(cè)試代碼同入門程序,將ini的地址修改為shiro-realm.ini。
分別模擬賬號(hào)不存在、密碼錯(cuò)誤、賬號(hào)和密碼正確進(jìn)行測(cè)試。
散列算法一般用于生成一段文本的摘要信息,散列算法不可逆,將內(nèi)容可以生成摘要,無(wú)法將摘要轉(zhuǎn)成原始內(nèi)容。散列算法常用于對(duì)密碼進(jìn)行散列,常用的散列算法有MD5、SHA。
一般散列算法需要提供一個(gè)salt(鹽)與原始內(nèi)容生成摘要信息,這樣做的目的是為了安全性,比如:111111的md5值是:96e79218965eb72c92a549dd5a330112,拿著“96e79218965eb72c92a549dd5a330112”去md5破解網(wǎng)站很容易進(jìn)行破解,如果要是對(duì)111111和salt(鹽,一個(gè)隨機(jī)數(shù))進(jìn)行散列,這樣雖然密碼都是111111加不同的鹽會(huì)生成不同的散列值。
[java]view plain copy print?
//md5加密,不加鹽
String password_md5 = new Md5Hash("111111").toString();
System.out.println("md5加密,不加鹽="+password_md5);
//md5加密,加鹽,一次散列
String password_md5_sale_1 = new Md5Hash("111111", "eteokues", 1).toString();
System.out.println("password_md5_sale_1="+password_md5_sale_1);
String password_md5_sale_2 = new Md5Hash("111111", "uiwueylm", 1).toString();
System.out.println("password_md5_sale_2="+password_md5_sale_2);
//兩次散列相當(dāng)于md5(md5())
//使用SimpleHash
String simpleHash = new SimpleHash("MD5", "111111", "eteokues",1).toString();
System.out.println(simpleHash);
實(shí)際應(yīng)用是將鹽和散列后的值存在數(shù)據(jù)庫(kù)中,自動(dòng)realm從數(shù)據(jù)庫(kù)取出鹽和加密后的值由shiro完成密碼校驗(yàn)。
[java]view plain copy print?
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
//用戶賬號(hào)
String username = (String) token.getPrincipal();
//根據(jù)用戶賬號(hào)從數(shù)據(jù)庫(kù)取出鹽和加密后的值
//..這里使用靜態(tài)數(shù)據(jù)
//如果根據(jù)賬號(hào)沒(méi)有找到用戶信息則返回null,shiro拋出異常“賬號(hào)不存在”
//按照固定規(guī)則加密碼結(jié)果 ,此密碼 要在數(shù)據(jù)庫(kù)存儲(chǔ),原始密碼 是111111,鹽是eteokues
String password = "cb571f7bd7a6f73ab004a70322b963d5";
//鹽,隨機(jī)數(shù),此隨機(jī)數(shù)也在數(shù)據(jù)庫(kù)存儲(chǔ)
String salt = "eteokues";
//返回認(rèn)證信息
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
username, password, ByteSource.Util.bytes(salt),getName());
return simpleAuthenticationInfo;
}
配置shiro-cryptography.ini
[html]view plain copy print?
[main]
#定義憑證匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次數(shù)
credentialsMatcher.hashIterations=1
#將憑證匹配器設(shè)置到realm
customRealm=com.sihai.shiro.authentication.realm.CustomRealm2
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm
測(cè)試代碼同上個(gè)章節(jié),注意修改ini路徑。