shiro教程2(自定義Realm)

通過shiro教程1我們發現僅僅將數據源信息定義在ini文件中與我們實際開發環境有很大不兼容,所以我們希望能夠自定義Realm。

自定義Realm的實現

創建自定義Realmjava類

創建一個java文件繼承AuthorizingRealm類,重寫兩個抽象方法

/**
* 自定義的Realm
* @author dengp
*
*/
public class MyRealm extends AuthorizingRealm{

\t/**
\t * 認證方法
\t * @param token
\t * \t就是我們在測試代碼中 定義的UsernamePasswordToken對象
\t * 有我們保存的需要驗證的賬號密碼信息
\t */
\t@Override
\tprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
\t\t// 獲取賬號信息
\t\tString principal = (String) token.getPrincipal();
\t\t// 正常邏輯此處應該根據賬號去數據庫中查詢,此處我們默認賬號為 root 密碼123456
\t\t// 驗證賬號
\t\tif(!"root".equals(principal)){
\t\t\t// 賬號錯誤
\t\t\treturn null;
\t\t}
\t\tString pwd = "123456";
\t\t// 驗證密碼
\t\tAuthenticationInfo info = new SimpleAuthenticationInfo(principal, pwd,"myrealm");
\t\treturn info;
\t}
\t
\t/**
\t * 授權方法

\t */
\t@Override
\tprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
\t\t// TODO Auto-generated method stub
\t\treturn null;
\t}
}
shiro教程2(自定義Realm)

配置ini.xml文件

[main]
#自定義 realm
customRealm=com.dpb.realm.MyRealm
#將realm設置到securityManager
securityManager.realms=$customRealm

測試

測試代碼和上個案例一模一樣

@Test
public void test() {
\t// 1.獲取SecurityManager工廠對象
\tFactory<securitymanager> factory =
\t\t\tnew IniSecurityManagerFactory("classpath:shiro.ini");
\t// 2.通過Factory對象獲取SecurityManager對象
\tSecurityManager securityManager = factory.getInstance();
\t// 3.將SecurityManager對象添加到當前運行環境中
\tSecurityUtils.setSecurityManager(securityManager);
\t
\t// 4.獲取Subject對象
\tSubject subject = SecurityUtils.getSubject();
\tAuthenticationToken token = new UsernamePasswordToken("root1", "12345");
\t// 登錄操作
\ttry {
\t\tsubject.login(token);
\t} catch (UnknownAccountException e) {
\t\tSystem.out.println("賬號出錯...");
\t} catch(IncorrectCredentialsException e){
\t\tSystem.out.println("密碼出錯...");
\t}
\t// 獲取登錄的狀態
\tSystem.out.println(subject.isAuthenticated());
}/<securitymanager>
shiro教程2(自定義Realm)

shiro教程2(自定義Realm)

shiro教程2(自定義Realm)

原理分析

為什麼要繼承AuthorizingRealm?

上個教程中我們完整的分析了認證的流程,我們發現在認證的過程核心代碼是此:

shiro教程2(自定義Realm)

核心方法是doGetAuthenticationInfo(token)
在Realm的結構中

shiro教程2(自定義Realm)

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

自定義的Realm什麼時候被調用的?

shiro教程2(自定義Realm)

密碼驗證什麼時候執行的?

注意:自定義Realm中只完成了賬號的認證。密碼認證還是在AuthenticatingRealm中完成的,只是我們在自定義Realm中完成了密碼的設置。

shiro教程2(自定義Realm)

shiro教程2(自定義Realm)

shiro教程2(自定義Realm)


分享到:


相關文章: