Shiro源碼分析系列:02.Filters的執(zhí)行流程

默認(rèn)Filter

name class effect
anon AnonymousFilter 都可以訪問(wèn)
authc FormAuthenticationFilter 登錄之后才能進(jìn)行訪問(wèn)垫挨,不包括remember me
user UserFilter 登錄用戶才可以訪問(wèn)靖榕,包含remember me
logout LogoutFilter 立即登出登陸
......

自定義Filter

不同的登陸處理邏輯需要繼承不同類型的FIlter,比如,依賴web表單登陸的業(yè)務(wù)需要繼承FormAuthenticationFilter荡碾,未登錄的接口都會(huì)重定向到LoginUrl哀峻。自己處理登陸邏輯(比如token)的接口應(yīng)該繼承PassThruAuthenticationFilter,登陸失敗可以返回錯(cuò)誤碼月洛。不過(guò)所有的Filter只是認(rèn)證結(jié)果不一致,整個(gè)認(rèn)證的邏輯都是一致的。
Shiro的Filter統(tǒng)一交給ShiroFilterFactoryBean處理,配置文件看起來(lái)像這樣:

 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="filters">
            <util:map>
                <entry key="jwt">
                    <bean class="**********.JwtAuthenticationFilter">
                        <property name="loginUrl" value="/jwtlogin"/>
                        <property name="successUrl" value="/mall/mallManage.sc.sc"/>
                    </bean>
                </entry>
                <entry key="authc">
                    <bean class="***********.WebFormAuthenticationFilter">
                        <property name="usernameParam" value="username"/>
                        <property name="passwordParam" value="password"/>
                        <property name="checkCode" value="checkCode"/>
                        <property name="pageId" value="pageId"/>
                        <property name="failureKeyAttribute" value="shiroLoginFailure"/>
                        <property name="loginUrl" value="/login.sc"/>
                        <property name="successUrl" value="/index.sc"/>
                    </bean>
                </entry>
                <!--<entry key="checkCode" value-ref="checkCodeAuthenticationFilter"/>-->
            </util:map>
        </property>
        <property name="filterChainDefinitionMap">
            <util:map>
                <entry key="/MemberCameraPoint/menberCameraPoin" value="anon"/>
                <entry key="/assets/**" value="anon"/>
                <entry key="/logout" value="logout"/>
                <entry key="/mobile/**" value="anon"/>
                <entry key="/wxlogin/**" value="anon"/>
                <entry key="/packageGoods/**" value="anon"/>
                <!--
                <entry key="/php/**" value="anon"/>
                <entry key="/api/**" value="anon"/>
                -->
                <entry key="/ueditor/**" value="anon"/>
                <entry key="/swagger-ui.html**" value="anon"/>
                <entry key="/redis/loadData" value="anon"/>
                <entry key="/pay/alipay/refund/notify" value="anon"/>
                <entry key="/act/**" value="anon"/>
                <entry key="/shutdown" value="anon"/>
                <entry key="/webjars/**" value="anon"/>
                <entry key="/swagger-resources/**" value="anon"/>
                <entry key="/v2/api-docs" value="anon"/>
                <entry key="/bindCheckCode" value="anon"/>
                <entry key="/gotoBindCheckCode" value="anon"/>
                <entry key="/erpcoupon/publishCampInfo" value="anon"/>
                <entry key="/system/tools/**" value="anon"/>
                <!--<entry key="/login.sc" value="checkCode,authc"/>-->
                <entry key="/jwtlogin/**" value="jwt"/>
                <entry key="/**" value="authc"/>
            </util:map>
        </property>
    </bean>

Filter執(zhí)行流程

下面的分析流程我們以Post提交表單登陸為例(FormAuthenticationFilter)撵术。
通過(guò)第一篇,我們已經(jīng)知道shrio是如何從Spring MVC中接管web請(qǐng)求的话瞧,并且循環(huán)調(diào)用配置的filters嫩与,接下來(lái)先看一張filter執(zhí)行的概覽圖:


2.0.Filter執(zhí)行流程.jpg
  1. 調(diào)用FormAuthenticationFilter.doFilter()方法,判斷當(dāng)前filter有沒(méi)有重復(fù)執(zhí)行;
  2. 調(diào)用doFilterInternal()交排,真正執(zhí)行fiter認(rèn)證流程划滋,執(zhí)行剩余的filter的鏈條,請(qǐng)求交給mvc的其他的filter埃篓;
  3. 調(diào)用preHandle方法处坪,返回值非常重要,決定當(dāng)前的請(qǐng)求要不要繼續(xù)走剩余的流程。

接下來(lái)稻薇,詳細(xì)分析preHandle方法的執(zhí)行流程:
1.先判斷當(dāng)前請(qǐng)求能否被處理


image.png
  1. 調(diào)用onPreHandle()方法
isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);

2.1 isAccessAllowed()本質(zhì)是從線程局部變量獲取Subject對(duì)象嫂冻,判斷是否授權(quán)。如果是fasle塞椎,就會(huì)判斷是否不是登陸請(qǐng)求&&filter忽略(返回true)桨仿。因?yàn)榈顷懻?qǐng)求交給下一步處理
如果返回true,則表示當(dāng)前請(qǐng)求已經(jīng)登陸或不是登陸請(qǐng)求且是該Filter忽略的案狠,直接放行服傍。
2.2 當(dāng)?shù)谝徊椒祷豧alse時(shí)候,就會(huì)調(diào)用onAccessDenied()方法骂铁,處理未認(rèn)證的邏輯吹零。


image.png

先判斷是否為登陸請(qǐng)求,再判斷是否是登陸提交表單拉庵。是登陸提交表單灿椅,就之心executeLogin方法,否則就放行這個(gè)filter钞支,跳轉(zhuǎn)登陸頁(yè)面茫蛹。
過(guò)不是登陸請(qǐng)求,重定向到登陸頁(yè)面烁挟,返回false婴洼,filter結(jié)束本次請(qǐng)求。

  1. executeLogin()執(zhí)行登陸請(qǐng)求方法


    image.png

    3.1 從登錄表單請(qǐng)求中獲取用戶名和密碼撼嗓,封裝為Token柬采,自定義Token可以重寫createToken()
    3.2 獲取Shiro的上文對(duì)象
    3.3 把包含登陸信息的token執(zhí)行登陸請(qǐng)求,具體調(diào)用Realm的登陸方法且警,上下文對(duì)象中就會(huì)存儲(chǔ)已經(jīng)成功認(rèn)證的信息粉捻,下次請(qǐng)求在2.1處就會(huì)直接放行。接下來(lái)會(huì)具體分析Realm的登陸流程斑芜。
    3.4 登陸成功回調(diào)的方法


    image.png

    至此杀迹,認(rèn)證的閉環(huán)流程完成,3.4的重定向的請(qǐng)求到達(dá)2.1的isAccessAllowed()就會(huì)返回true押搪,filter直接放行這個(gè)請(qǐng)求树酪。
    接下的章節(jié)會(huì)詳細(xì)分析登陸的subject.login()方法和Subject對(duì)象如何讓存儲(chǔ)登陸信息。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末大州,一起剝皮案震驚了整個(gè)濱河市续语,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌厦画,老刑警劉巖疮茄,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滥朱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡力试,警方通過(guò)查閱死者的電腦和手機(jī)徙邻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)畸裳,“玉大人缰犁,你說(shuō)我怎么就攤上這事〔篮” “怎么了帅容?”我有些...
    開(kāi)封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)伍伤。 經(jīng)常有香客問(wèn)我并徘,道長(zhǎng),這世上最難降的妖魔是什么扰魂? 我笑而不...
    開(kāi)封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任麦乞,我火速辦了婚禮,結(jié)果婚禮上劝评,老公的妹妹穿的比我還像新娘路幸。我一直安慰自己,他們只是感情好付翁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著晃听,像睡著了一般百侧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上能扒,一...
    開(kāi)封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天佣渴,我揣著相機(jī)與錄音,去河邊找鬼初斑。 笑死辛润,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的见秤。 我是一名探鬼主播砂竖,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鹃答!你這毒婦竟也來(lái)了乎澄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤测摔,失蹤者是張志新(化名)和其女友劉穎置济,沒(méi)想到半個(gè)月后解恰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浙于,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年护盈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羞酗。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腐宋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出整慎,到底是詐尸還是另有隱情脏款,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布裤园,位于F島的核電站撤师,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拧揽。R本人自食惡果不足惜剃盾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淤袜。 院中可真熱鬧痒谴,春花似錦、人聲如沸铡羡。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)烦周。三九已至尽爆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間读慎,已是汗流浹背漱贱。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夭委,地道東北人幅狮。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像株灸,于是被迫代替她去往敵國(guó)和親崇摄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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

  • Getting Started Burp Suite 是用于攻擊web 應(yīng)用程序的集成平臺(tái)慌烧。它包含了許多工具配猫,并為...
    Eva_chenx閱讀 28,658評(píng)論 0 14
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)杏死。 注意:講述HT...
    kismetajun閱讀 27,449評(píng)論 1 45
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,092評(píng)論 1 32
  • 本文包括:1泵肄、Filter簡(jiǎn)介2捆交、Filter是如何實(shí)現(xiàn)攔截的?3腐巢、Filter開(kāi)發(fā)入門4品追、Filter的生命周期...
    廖少少閱讀 7,256評(píng)論 3 56
  • 模塊間聯(lián)系越多,其耦合性越強(qiáng)冯丙,同時(shí)表明其獨(dú)立性越差( 降低耦合性肉瓦,可以提高其獨(dú)立性)。軟件設(shè)計(jì)中通常用耦合度和內(nèi)聚...
    riverstation閱讀 2,064評(píng)論 0 8