您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Shiro的登錄流程以及Realm的簡單介紹”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
首先我們來看 shiro 官方文檔中這樣一張登錄流程圖:
參照此圖,我們的登錄一共要經(jīng)過如下幾個步驟:
應用程序代碼調(diào)用 Subject.login 方法,傳遞創(chuàng)建好的包含終端用戶的 Principals(身份)和 Credentials(憑證)的 AuthenticationToken 實例(即上文例子中的 UsernamePasswordToken)。
Subject 實例,通常是 DelegatingSubject(或子類)委托應用程序的 SecurityManager 通過調(diào)用 securityManager.login(token) 開始真正的驗證工作(在 DelegatingSubject 類的 login 方法中打斷點即可看到)。
SubjectManager 作為一個基本的“保護傘”的組成部分,接收 token 以及簡單地委托給內(nèi)部的 Authenticator 實例通過調(diào)用 authenticator.authenticate(token)。這通常是一個 ModularRealmAuthenticator 實例,支持在身份驗證中協(xié)調(diào)一個或多個 Realm 實例。ModularRealmAuthenticator 本質(zhì)上為 Apache Shiro 提供了 PAM-style 范式(其中在 PAM 術語中每個 Realm 都是一個'module')。
如果應用程序中配置了一個以上的 Realm,ModularRealmAuthenticator 實例將利用配置好的 AuthenticationStrategy 來啟動 Multi-Realm 認證嘗試。在 Realms 被身份驗證調(diào)用之前,期間和以后,AuthenticationStrategy 被調(diào)用使其能夠對每個 Realm 的結果作出反應。如果只有一個單一的 Realm 被配置,它將被直接調(diào)用,因為沒有必要為一個單一 Realm 的應用使用 AuthenticationStrategy。
每個配置的 Realm 用來幫助看它是否支持提交的 AuthenticationToken。如果支持,那么支持 Realm 的 getAuthenticationInfo 方法將會伴隨著提交的 token 被調(diào)用。
OK,通過上面的介紹,相信小伙伴們對整個登錄流程都有一定的理解了,小伙伴可以通過打斷點來驗證我們上文所說的五個步驟。那么在上面的五個步驟中,小伙伴們看到了有一個 Realm 承擔了很重要的一部分工作,那么這個 Realm 到底是個什么東西,接下來我們就來仔細看一看。
根據(jù) Realm 文檔上的解釋,Realms 擔當 Shiro 和你的應用程序的安全數(shù)據(jù)之間的“橋梁”或“連接器”。當它實際上與安全相關的數(shù)據(jù)如用來執(zhí)行身份驗證(登錄)及授權(訪問控制)的用戶帳戶交互時,Shiro 從一個或多個為應用程序配置的 Realm 中尋找許多這樣的東西。在這個意義上說,Realm 本質(zhì)上是一個特定安全的 DAO:它封裝了數(shù)據(jù)源的連接詳細信息,使 Shiro 所需的相關的數(shù)據(jù)可用。當配置 Shiro 時,你必須指定至少一個 Realm 用來進行身份驗證和/或授權。SecurityManager 可能配置多個 Realms,但至少有一個是必須的。Shiro 提供了立即可用的 Realms 來連接一些安全數(shù)據(jù)源(即目錄),如 LDAP,關系數(shù)據(jù)庫(JDBC),文本配置源,像 INI 及屬性文件,以及更多。你可以插入你自己的 Realm 實現(xiàn)來代表自定義的數(shù)據(jù)源,如果默認地 Realm 不符合你的需求。
看了上面這一段解釋,可能還有小伙伴云里霧里,那么接下來我們來通過一個簡單的案例來看看 Realm 到底扮演了一個什么樣的作用,注意,本文的案例在上文案例的基礎上完成。首先自定義一個 MyRealm,內(nèi)容如下:
public class MyRealm implements Realm {
public String getName() {
return "MyRealm";
}
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String password = new String(((char[]) token.getCredentials()));
String username = token.getPrincipal().toString();
if (!"sang".equals(username)) {
throw new UnknownAccountException("用戶不存在");
}
if (!"123".equals(password)) {
throw new IncorrectCredentialsException("密碼不正確");
}
return new SimpleAuthenticationInfo(username, password, getName());
}
}
自定義 Realm 實現(xiàn) Realm 接口,該接口中有三個方法,第一個 getName 方法用來獲取當前 Realm 的名字,第二個 supports 方法用來判斷這個 realm 所支持的 token,這里我假設值只支持 UsernamePasswordToken 類型的 token,第三個 getAuthenticationInfo 方法則進行了登陸邏輯判斷,從 token 中取出用戶的用戶名密碼等,進行判斷,當然,我這里省略掉了數(shù)據(jù)庫操作,當?shù)卿涷炞C出現(xiàn)問題時,拋異常即可,這里拋出的異常,將在執(zhí)行登錄那里捕獲到(注意,由于我這里定義的 MyRealm 是實現(xiàn)了 Realm 接口,所以這里的用戶名和密碼都需要我手動判斷是否正確,后面的文章我會介紹其他寫法)。
OK,創(chuàng)建好了 MyRealm 之后還不夠,我們還需要做一個簡單配置,讓 MyRealm 生效,將 shiro.ini 文件中的所有東西都注釋掉,添加如下兩行:
MyRealm= org.sang.MyRealm
securityManager.realms=$MyRealm
“Shiro的登錄流程以及Realm的簡單介紹”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。