shiro教程2(自定義Realm)


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

自定義Realm的實現

創建自定義Realmjava類

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

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

	/**
	 * 認證方法
	 * @param token 
	 * 	就是我們在測試代碼中 定義的UsernamePasswordToken對象
	 *  有我們保存的需要驗證的賬號密碼信息
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 獲取賬號信息
		String principal = (String) token.getPrincipal();
		// 正常邏輯此處應該根據賬號去數據庫中查詢,此處我們默認賬號為 root 密碼123456
		// 驗證賬號
		if(!"root".equals(principal)){
			// 賬號錯誤
			return null;
		}
		String pwd = "123456";
		// 驗證密碼
		AuthenticationInfo info = new SimpleAuthenticationInfo(principal, pwd,"myrealm");
		return info;
	}
	
	/**
	 * 授權方法
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// TODO Auto-generated method stub
		return null;
	}
}
方法名 說明
doGetAuthenticationInfo 完成賬號認證的方法
doGetAuthorizationInfo 完成用戶授權的方法

配置ini.xml文件

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

測試

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

@Test
public void test() {
	// 1.獲取SecurityManager工廠對象
	Factory<SecurityManager> factory = 
			new IniSecurityManagerFactory("classpath:shiro.ini");
	// 2.通過Factory對象獲取SecurityManager對象
	SecurityManager securityManager = factory.getInstance();
	// 3.將SecurityManager對象添加到當前運行環境中
	SecurityUtils.setSecurityManager(securityManager);
	
	// 4.獲取Subject對象
	Subject subject = SecurityUtils.getSubject();
	AuthenticationToken token = new UsernamePasswordToken("root1", "12345");
	// 登錄操作
	try {
		subject.login(token);
	} catch (UnknownAccountException e) {
		System.out.println("賬號出錯...");
	} catch(IncorrectCredentialsException e){
		System.out.println("密碼出錯...");
	}
	// 獲取登錄的狀態
	System.out.println(subject.isAuthenticated());
}

在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述

原理分析

為什么要繼承AuthorizingRealm?

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

在這里插入圖片描述
核心方法是doGetAuthenticationInfo(token)
在Realm的結構中
在這里插入圖片描述

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

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

在這里插入圖片描述

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

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

在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM