Shiro登錄校驗流程實現(xiàn)與分析

什么是Shiro

Apache Shiro是一個強大且易用的Java安全框架,執(zhí)行身份驗證轨奄、授權(quán)挽铁、密碼和會話管理袋倔。使用Shiro的易于理解的API,您可以快速坦辟、輕松地獲得任何應(yīng)用程序,從最小的移動應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序。

三個核心組件

Subject, SecurityManager 和 Realms.
①Subject:即“當(dāng)前操作用戶”声离。但是芒炼,在Shiro中,Subject這一概念并不僅僅指人术徊,也可以是第三方進程本刽、后臺帳戶(Daemon Account)或其他類似事物。它僅僅意味著“當(dāng)前跟軟件交互的東西”。但考慮到大多數(shù)目的和用途盅安,你可以把它認為是Shiro的“用戶”概念唤锉。Subject代表了當(dāng)前用戶的安全操作,SecurityManager則管理所有用戶的安全操作别瞭。
②SecurityManager:它是Shiro框架的核心窿祥,典型的Facade模式,Shiro通過SecurityManager來管理內(nèi)部組件實例蝙寨,并通過它來提供安全管理的各種服務(wù)晒衩。
③Realm: Realm充當(dāng)了Shiro與應(yīng)用安全數(shù)據(jù)間的“橋梁”或者“連接器”。也就是說墙歪,當(dāng)對用戶執(zhí)行認證(登錄)和授權(quán)(訪問控制)驗證時听系,Shiro會從應(yīng)用配置的Realm中查找用戶及其權(quán)限信息。

登錄認證過程簡述

①調(diào)用subject.login方法進行登錄虹菲,其會自動委托給securityManager,login方法進行登錄;
②securityManager通過 Authenticator(認證器)進行認證
③Authenticator的實現(xiàn)ModularRealmAuthenticaton調(diào)用realm從ini配置文件取用戶真實的賬號和密碼靠胜,這里使用的是IniRealm ( shiro自帶,相當(dāng)于數(shù)據(jù)源) ;

④IniRealm先根據(jù)token中的賬號去ini中找該賬號,如果找不到則給ModularRealmAuthenticator返回null ,如果找到則匹配密碼毕源,匹配密碼成功則認證通過浪漠。
image.png
具體實現(xiàn)
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.4.0</version>
    </dependency>
image.png
package com.swl;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;

/**
 * <Description>ShiroTest<br>
 *
 * @author DaShi<br>
 * @CreateDate 2019-02-15 09:43 <br>
 */
public class ShiroTest {
    @Test
    public void loginTest() throws Exception{
        //創(chuàng)建IniSecurityManager工程對象:加載配置文件
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //通過工廠對象創(chuàng)建SecurityManager對象
        SecurityManager securityManager = factory.getInstance();
        // 將SecurityManager綁定到當(dāng)前運行環(huán)境中,讓系統(tǒng)隨時可以訪問SecurityManager對象
        SecurityUtils.setSecurityManager(securityManager);

        //創(chuàng)建登錄主體 注意:此時主體沒有經(jīng)過驗證霎褐,僅僅是個空的對象
        Subject subject = SecurityUtils.getSubject();
        //綁定主體登陸的身份址愿、憑證 即賬號密碼
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
        //主體登陸
        try{
            subject.login(token);
        }catch (Exception e){
            //拋錯誤
        }
        //登陸判斷
        System.out.println("登錄結(jié)果" + subject.isAuthenticated() );
        //登出判斷
        subject.logout();
        System.out.println("登出結(jié)果" + subject.isAuthenticated());
    }
}

結(jié)果:


image.png
源碼分析

①我們在登錄操作時打好斷點,debug運行
image.png

②我們進入到subject主體的實現(xiàn)類中冻璃,注意標(biāo)記部分响谓,subject將登錄操作委托給了securitymanager,參數(shù)除了頁面?zhèn)魅氲膖oken以外還有subject主體
image.png
③進入到securitymanager實現(xiàn)類中省艳,開始執(zhí)行認證方法
image.png

④點進去看一下娘纷,我們發(fā)現(xiàn)securitymanager將認證任務(wù)委托給了認證器,由認證器執(zhí)行認證方法
image.png

⑤我們進入到認證方法中
image.png
⑥繼續(xù)執(zhí)行doAuthenticate跋炕,我們發(fā)現(xiàn)這里面有個realm失驶,他是啥呢?
image.png
我們看到realms這個集合里面其實就是我們之前加載的realms.ini中的內(nèi)容
image.png
⑦因為我們只有一個realm枣购,所以進入了true條件中,這時我們剛才標(biāo)記出的AuthenticationInfo出現(xiàn)了擦耀,看看他是啥
image.png
點進去看看
image.png

看不懂棉圈,繼續(xù)進去看看,我們看到他先把我們的token包裝成了 UsernamePasswordToken的形式 然后執(zhí)行了getuser()參數(shù)是我們頁面?zhèn)鬟M來的token的name
image.png
⑧我們看一下里面是什么眷蜓,是通過頁面?zhèn)魅氲哪莻€用戶名分瘾,去我們剛才realm里面的user列表去查找有沒有這個用戶 如果找到了,將realm中該用戶信息返回上一層
image.png

⑨這時我們可以看到account中包含了張三的信息
image.png
⑩接下來我們繼續(xù)返回上一層吁系,因為我們已經(jīng)在realm中找到了頁面輸入的token的用戶名德召,下一步進行密碼驗證
image.png
密碼驗證就很簡單了白魂,重點就是這個判斷
image.png
其實就是把我們剛才取得的那個realm中的張三的密碼和我們頁面?zhèn)魅氲拿艽a比較
image.png

好了整個過程大概就是這個樣子啦!I细凇福荸!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市肴掷,隨后出現(xiàn)的幾起案子敬锐,更是在濱河造成了極大的恐慌,老刑警劉巖呆瞻,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件台夺,死亡現(xiàn)場離奇詭異,居然都是意外死亡痴脾,警方通過查閱死者的電腦和手機颤介,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赞赖,“玉大人滚朵,你說我怎么就攤上這事∈矶ǎ” “怎么了始绍?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長话侄。 經(jīng)常有香客問我亏推,道長,這世上最難降的妖魔是什么年堆? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任吞杭,我火速辦了婚禮,結(jié)果婚禮上变丧,老公的妹妹穿的比我還像新娘芽狗。我一直安慰自己,他們只是感情好痒蓬,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布童擎。 她就那樣靜靜地躺著,像睡著了一般攻晒。 火紅的嫁衣襯著肌膚如雪顾复。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天鲁捏,我揣著相機與錄音芯砸,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛假丧,可吹牛的內(nèi)容都是我干的双揪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼包帚,長吁一口氣:“原來是場噩夢啊……” “哼渔期!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婴噩,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤擎场,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后几莽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迅办,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年章蚣,在試婚紗的時候發(fā)現(xiàn)自己被綠了站欺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡纤垂,死狀恐怖矾策,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情峭沦,我是刑警寧澤贾虽,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吼鱼,受9級特大地震影響蓬豁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菇肃,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一地粪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琐谤,春花似錦蟆技、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至织阳,卻和暖如春几苍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背陈哑。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惊窖。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓刽宪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親界酒。 傳聞我的和親對象是個殘疾皇子圣拄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容