shiro教程2(自定義Realm)

通過shiro教程1,我們了解到僅僅在ini文件中定義數(shù)據(jù)源信息與實(shí)際開發(fā)環(huán)境存在較大的不兼容性,因此我們希望能夠自定義realm。

實(shí)現(xiàn)自定義Realm的步驟如下:

  1. 創(chuàng)建自定義Realm的Java:新建一個(gè)Java文件,繼承AuthorizingRealm類,并重寫兩個(gè)抽象方法。
/**  * 自定義的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; }

}

shiro教程2(自定義Realm)

  1. 配置ini.xml文件
[main]</p><h1>自定義 realm</h1><p>customRealm=com.dpb.realm.MyRealm</p><h1>將realm設(shè)置到securityManager</h1><p>securityManager.realms=$customRealm
  1. 測(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());

}

shiro教程2(自定義Realm)shiro教程2(自定義Realm)shiro教程2(自定義Realm)

原理分析

在上個(gè)教程中,我們完整地分析了認(rèn)證的流程,發(fā)現(xiàn)認(rèn)證過程的核心代碼是:

shiro教程2(自定義Realm)

核心方法是doGetAuthenticationInfo(token),在Realm的結(jié)構(gòu)中:

shiro教程2(自定義Realm)

AuthorizingRealm和AuthenticatingRealm都提供了doGetAuthenticationInfo(token)的抽象方法。但是AuthenticatingRealm中需要重寫的抽象方法太多,而AuthorizingRealm只需要重寫兩個(gè)方法,且這兩個(gè)方法都是我們需要使用的。因此選擇繼承AuthorizingRealm。

  • 自定義的Realm什么時(shí)候被調(diào)用?

shiro教程2(自定義Realm)

  • 密碼驗(yàn)證什么時(shí)候執(zhí)行?

注意:自定義Realm中只完成了賬號(hào)的認(rèn)證。密碼認(rèn)證還是在AuthenticatingRealm中完成的,只是我們?cè)谧远xRealm中完成了密碼的設(shè)置。

shiro教程2(自定義Realm)shiro教程2(自定義Realm)shiro教程2(自定義Realm)

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊14 分享