通過shiro教程1,我們了解到僅僅在ini文件中定義數(shù)據(jù)源信息與實(shí)際開發(fā)環(huán)境存在較大的不兼容性,因此我們希望能夠自定義realm。
實(shí)現(xiàn)自定義Realm的步驟如下:
/** * 自定義的Realm * @author dengp */ public class MyRealm extends AuthorizingRealm { <pre class="brush:php;toolbar:false">/** * 認(rèn)證方法 * @param Token 就是我們?cè)跍y(cè)試代碼中定義的UsernamePasswordToken對(duì)象 * 有我們保存的需要驗(yàn)證的賬號(hào)密碼信息 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 獲取賬號(hào)信息 String principal = (String) token.getPrincipal(); // 正常邏輯此處應(yīng)該根據(jù)賬號(hào)去數(shù)據(jù)庫中查詢,此處我們默認(rèn)賬號(hào)為 root 密碼123456 // 驗(yàn)證賬號(hào) if(!"root".equals(principal)){ // 賬號(hào)錯(cuò)誤 return null; } String pwd = "123456"; // 驗(yàn)證密碼 AuthenticationInfo info = new SimpleAuthenticationInfo(principal, pwd, "myrealm"); return info; } /** * 授權(quán)方法 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // TODO Auto-generated method stub return null; }
}
- 配置ini.xml文件:
[main]</p><h1>自定義 realm</h1><p>customRealm=com.dpb.realm.MyRealm</p><h1>將realm設(shè)置到securityManager</h1><p>securityManager.realms=$customRealm
- 測(cè)試:測(cè)試代碼與上個(gè)案例完全相同。
@Test public void test() { // 1.獲取SecurityManager工廠對(duì)象 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");</p><pre class="brush:php;toolbar:false">// 2.通過Factory對(duì)象獲取SecurityManager對(duì)象 SecurityManager securityManager = factory.getInstance(); // 3.將SecurityManager對(duì)象添加到當(dāng)前運(yùn)行環(huán)境中 SecurityUtils.setSecurityManager(securityManager); // 4.獲取Subject對(duì)象 Subject subject = SecurityUtils.getSubject(); AuthenticationToken token = new UsernamePasswordToken("root1", "12345"); // 登錄操作 try { subject.login(token); } catch (UnknownAccountException e) { System.out.println("賬號(hào)出錯(cuò)..."); } catch(IncorrectCredentialsException e){ System.out.println("密碼出錯(cuò)..."); } // 獲取登錄的狀態(tài) System.out.println(subject.isAuthenticated());
}
原理分析:
- 為什么要繼承AuthorizingRealm?
在上個(gè)教程中,我們完整地分析了認(rèn)證的流程,發(fā)現(xiàn)認(rèn)證過程的核心代碼是:
核心方法是doGetAuthenticationInfo(token),在Realm的結(jié)構(gòu)中:
AuthorizingRealm和AuthenticatingRealm都提供了doGetAuthenticationInfo(token)的抽象方法。但是AuthenticatingRealm中需要重寫的抽象方法太多,而AuthorizingRealm只需要重寫兩個(gè)方法,且這兩個(gè)方法都是我們需要使用的。因此選擇繼承AuthorizingRealm。
- 自定義的Realm什么時(shí)候被調(diào)用?
- 密碼驗(yàn)證什么時(shí)候執(zhí)行?
注意:自定義Realm中只完成了賬號(hào)的認(rèn)證。密碼認(rèn)證還是在AuthenticatingRealm中完成的,只是我們?cè)谧远xRealm中完成了密碼的設(shè)置。
? 版權(quán)聲明
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載。
THE END