Shiro的authc過濾器的執行流程

1.先執行isAccessAllowed(),通過subject.isAuthenticated()判斷當前session中的subject是否已經登陸過。如果在當前session即會話中已經登陸過,返回true,authc過濾器放行請求到loginUrl。
問題?
這里會有一個問題,如果我登陸成功后,再次訪問loginUrl,會執行isAccessAllowed()并返回true放行,那么我訪問到了loginUrl,如果此時我在loginUrl中輸入新的用戶名密碼,再提交則先執行isAccessAllowed(),因為當前session中的subject是已經登陸過的,isAccessAllowed()返回true,autch放行,請求又會到loginUrl。因為在登陸的情況下,再訪問loginUrl則isAccessAllowed()始終返回true,不會執行到onAccessDenied()方法,即不會驗證請求中的新的用戶名和密碼。
2.如果isAccessAllowed()是false即拒絕訪問后執行onAccessDenied()方法:
2.1判斷是否是登陸請請求(即request中的url和我們設置的loginUrl是否一致)
2.1.1如果請求的url和我們在配置文件中設置的loginUrl一樣
2.1.1.1如果是get請求,則返回true,即該過濾器連放行,讓請求訪問到loginUrl
2.1.1.2如果是post請求,則創建subjet和tocken 調用subject的login方法進行認證(即開始執行realm的doGetAuthenticationInfo方法)
2.1.1.2.1如果認證成功則會返回false阻止filterChain繼續執行即不讓請求達到loginUrl,而是在這里直接重定向我們上次訪問的非logurl的請求地址去(這個請求地址在你訪問的時候已經被保存到session中了)如果沒有上次訪問的地址,則到我們設置的SuccessUrl
2.1.1…2.2如果認證失敗則會返回true,將認證失敗的異常信息放到reqeust屬性中,即放行讓fliterChain繼續執行,讓請求達到loginUrl。
2.2如果否即request中的url不是loginUrl,則保存請求(應該是到session里),再將請求重定向到loginUrl(瀏覽器又會訪問通過get方法訪問loginUrl,又會被authc攔截,再重複上面流程,此時是登陸請求且是GET請求則authc會放行訪問到loginUrl),執行完重定向后返回false阻止filterChain繼續執行。

綜上所述:
只有以下四種情況會到loginUrl:
//1.還沒有登陸成功的情況下:get請求我們在配置文件中設置的loginUrl,authc會放行請求到這里
//2.還沒有登陸成功的情況下:post請求我們在配置文件中設置的loginUrl,authc在認證失敗后會讓瀏覽器重定向到這里
//3.還沒有登陸成功的情況下:請求(不管post還是get)的頁面不是loginUrl且需要authc過濾,那么authc也會讓瀏覽器重定向到這里
//4.登陸成功后,瀏覽器再次訪問loginUrl(不管post或get),authc也會放行到這里。
怎么解決上面登陸成功后再訪問loginUrl,不會執行新用戶認證的問題呢?只有重寫authc過濾器的isAccessAllowed()方法

public class MyAuthcFilter extends FormAuthenticationFilter {@Overrideprotected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue){System.out.println("執行自定義過濾");//如果請求的是loginUrl 并且是POST請求,那么肯定是要驗證密碼的,這里直接返回false 就會執行onAcessDenied()方法if (isLoginRequest(request, response) && isLoginSubmission(request, response)){return false;}//如果是其他請求 則執行父類的方法return super.isAccessAllowed(request, response, mappedValue);}
}

最后再配置文件中注冊該類,覆蓋掉shiro原本的過濾器FormAuthenticationFilter:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><property name="loginUrl" value="/login" /><property name="successUrl" value="/index.jsp" /><property name="unauthorizedUrl" value="/unauthorized.jsp" /><property name="filters"><map><entry key="authc" value-ref="myAuthcFilter" /></map></property><property name="filterChainDefinitions"><value># some example chain definitions:/login = authc/logout = logout/1.jsp = user/** = authc# more URL-to-FilterChain definitions here</value></property></bean>

login的寫法:

@Controller
public class UsersController {@RequestMapping("login")public String login(HttpServletRequest req) {//只有//1.還沒有登陸成功的情況下:get請求我們在配置文件中設置的loginUrl,authc會放行請求到這里//2.還沒有登陸成功的情況下:post請求我們在配置文件中設置的loginUrl,authc在認證失敗后會讓瀏覽器重定向到這里//3.還沒有登陸成功的情況下:請求(不管post還是get)的頁面不是loginUrl且需要authc過濾,那么authc也會讓瀏覽器重定向到這里//4.登陸成功后,瀏覽器再次訪問loginUrl(不管post或get),authc也會放行到這里。如果我們在自定義的過濾器中//設置成如果是POST請求的loginUrl,我們返回false。那么post請求的loginUrl就會執行在過濾器中執行onAcessDenied()方法,如果post的loginUrl驗證失敗了會到這里,如果驗證成功則到secessUrl這里。String errorClassName = (String) req.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);if(UnknownAccountException.class.getName().equals(errorClassName)) {req.setAttribute("error", "用戶名/密碼錯誤");} else if(IncorrectCredentialsException.class.getName().equals(errorClassName)) {req.setAttribute("error", "用戶名/密碼錯誤");} else if(errorClassName != null) {req.setAttribute("error", "未知錯誤:" + errorClassName);}return "login.jsp";}
}

session和cookie:
通過瀏覽器第一次發送http請求時,服務器會創建一個session和cookie(cookie中保存sessionid),這個session服務器的默認時間30分鐘,可以設置。服務第一次響應時也把cookie放到響應中給瀏覽器,瀏覽器
收到cookie后,會判斷cookie有沒有設置過期時間,如果沒有則只保存在內存中。如果有則存到硬盤里。
如果只是保存到內存中,服務器端的session依然會保留30分鐘。那么瀏覽器一關閉,cookie消失,sessionid也消失了。。但此時打開瀏覽器再訪問服務器時,雖然服務器的session依然存在,但瀏覽器中的cookie(sessionid)消失了
瀏覽器發送的請求頭里沒有cookie(沒有sessionid),服務器會當作一個新的請求,會再創建一個新session。服務器中的之前的session 30分鐘侯清除。
如果保存到硬盤里了, 服務器端的session依然會保留30分鐘。那么關閉瀏覽器后,再打開瀏覽器訪問服務器時,瀏覽器會找到存到硬盤里的cookie(sessionId), 瀏覽器再次請求服務器時會帶上cookie,服務器收到請求后發現有cookie(sessionId)并且服務器
端的session也存在。那么服務器就依然會使用之前的session。不會再創建一個新的session。
所以session默認關閉瀏覽器就失效了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250068.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250068.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250068.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot之基礎

簡介 背景 J2EE笨重的開發 / 繁多的配置 / 低下的開發效率 / 復雜的部署流程 / 第三方技術集成難度大 特點 ① 快速創建獨立運行的spring項目以及主流框架集成 ② 使用嵌入式的Servlet容器, 應用無需達成war包 ③ starters自動依賴和版本控制 ④ 大量自動配置, 簡化開發, 也可修…

[Java核心技術(卷I)] - vscode手動編譯運行繼承類

參考 - P160~P161 主要有3個類: 一個測試類(ManagerTest)、一個子類(Manager)、一個父類(Employee) 注意點: -1. 使用 javac -d . *.java進行預編譯 目錄結構入下: 此時會生成目錄結構如下: 之后運行 java com.inheritance.ManagerTest 附上幾個類的代碼 // com.inhe…

mysql常用語句和函數

mysql語句如果長期不寫&#xff0c;就會忘掉&#xff0c;所以要時常復習&#xff0c;溫故而知新。 1.select length("中國人"),select char_length("中國人"); 2建立數據庫的語句 use new_schema;create table ta(id int primary key);這是小括號&#xff…

shiro框架@RequiresPermissions 解釋

RequiresAuthentication 驗證用戶是否登錄&#xff0c;等同于方法subject.isAuthenticated() 結果為true時。 RequiresUser 驗證用戶是否被記憶&#xff0c;user有兩種含義&#xff1a; 一種是成功登錄的&#xff08;subject.isAuthenticated() 結果為true&#xff09;&…

【Social Listening實戰】當數據分析遭遇心理動力學:用戶深層次的情感需求浮出水面...

本文轉自知乎 作者&#xff1a;蘇格蘭折耳喵 ————————————————————————————————————————————————————— 本文篇幅較長&#xff0c;分為五部分&#xff0c;在中間部分有關于心理分析工具的介紹&#xff0c;案例分散在第二部…

Python 字符串切片

#-*- coding:utf-8 -*-#字符串切片names "abcdefgh"切片語法 names[起始位置:終止位置:步長] 起始位置:即字符串的下標&#xff0c;可以是正序下標(0,1,2...)&#xff0c;也可以是逆序下標(-1,-2,-3...) 終止位置:也是字符串的下標&#xff0c;但是和起始位置下標不…

[Java核心技術(卷Ⅰ)] - 判斷相等

參考 - P184 public boolean equals(Object otherObject) {// a quick test to see if the objects are identicalif (this otherObject) return true;// must return false if the explicit parameter is nullif (otherObject null) return null;// if the classes dont ma…

Oracle 11g DG主庫節點2 ORA-00245: control file backup fail

--節點1報錯 Sun Dec 09 08:29:57 2018Control file backup creation failed: failure to open backup target file /u01/app/oracle/product/11.2.0/db_1/dbs/snapcf_zwdb.ctl.Errors in file /u01/app/oracle/diag/rdbms/zwdb/zwdb2/trace/zwdb2_arc0_167660.trc:ORA-27037: …

hive字符函數

轉載于:https://www.cnblogs.com/ggzhangxiaochao/p/9222732.html

java動態編譯

編譯&#xff0c;一般來說就是將源代碼轉換成機器碼的過程&#xff0c;比如在C語言中中&#xff0c;將C語言源代碼編譯成a.out,&#xff0c;但是在Java中的理解可能有點不同&#xff0c;編譯指的是將java 源代碼轉換成class字節碼的過程&#xff0c;而不是真正的機器碼&#xf…

[c++] - 簡單的冒泡

#include <iostream> using namespace std;int main() {// 利用冒泡排序實現升序序列int arr[9] {4, 2, 8, 0, 5, 7, 1, 3, 9};cout << "排序前: " << endl;for (int i 0; i < 9; i){cout << arr[i] << " ";}cout <…

Python爬蟲之解析網頁

常用的類庫為lxml, BeautifulSoup, re(正則) 以獲取豆瓣電影正在熱映的電影名為例,urlhttps://movie.douban.com/cinema/nowplaying/beijing/ 網頁分析 部分網頁源碼 <ul class"lists"><liid"3878007"class"list-item"data-title"…

騰訊企業郵箱報錯 smtp.exmail.qq.comport 465, isSSL false

一、報錯 "smtp.exmail.qq.com" port 465, isSSL false 通過網上搜索查詢一些資料&#xff0c;推測是郵箱的配置出問題了。 二、修改郵箱配置 1 // 創建屬性2 Properties props new Properties();3 props.setProperty("mail.transport.protocol", "s…

spring與JDK版本對應關系

搭建spring框架得時候要考慮jdk的版本&#xff0c;提供一下參考 JDK 8 中可以使用 Spring Framework 5.x JDK 7 中可以使用 Spring Framework 4.x JDK 6 中可以使用 Spring Framework 4.x JDK 5 中可以使用 Spring Framework 3.x

Markdown預覽功能不可用解決方案

初學者在使用Markdown時也許會遇到這個問題 原因是電腦缺少一個組件&#xff0c;解決方案很簡單&#xff0c;安裝上就好了&#xff0c;以下是鏈接 http://markdownpad.com/download/awesomium_v1.6.6_sdk_win.exe轉載于:https://www.cnblogs.com/j9oker/p/10092829.html

Linux 中yum的配置

1.進入yum的路徑 cd /etc/yum.repos.d 2.將原始的repo文件移入一個新建的backup文件下做備份 mv CentOS* backup 3.在/etc/yum.repos.d下新建一個自己的文件(這里的文件必須以repo結尾); vi zhi.repo 其中&#xff0c;第一行必須是[文件名]的格式  是一個標記 name*** 這是一…

[生態建設] - js判斷小技巧

0、參考 說明: 從幾個易得的點出發,逐步向外擴展延申,保證代碼的可靠性 1、判斷是否為某個類型 // 判斷是否為 null const isNull o > {return o null; };// 判斷是否為 undefined const isUndefined o > {return o undefined; };// 判斷是否為 null or undefined…

Spring中Bean的概念

一、Bean的定義 <beans…/>元素是Spring配置文件的根元素&#xff0c;<beans…/>元素可以包含多個<bean…/>子元素&#xff0c;每個<bean…/>元素可以定義一個Bean實例&#xff0c;每一個Bean對應Spring容器里的一個Java實例定義Bean時通常需要指定兩…

[TJOI2010]閱讀理解

題目描述 英語老師留了N篇閱讀理解作業&#xff0c;但是每篇英文短文都有很多生詞需要查字典&#xff0c;為了節約時間&#xff0c;現在要做個統計&#xff0c;算一算某些生詞都在哪幾篇短文中出現過。 輸入輸出格式 輸入格式&#xff1a; 第一行為整數N&#xff0c;表示短文篇…

ccentos 7下安裝php5.6并使用nginx + php-fpm部署多個不同端口網站

作為一個的勤雜工&#xff0c;近期因公司內部信息化的需求&#xff0c;給新進員工提供基礎的知識培訓和介紹&#xff0c;也為了給公司內部建立一個溝通交流的平臺&#xff0c;百度找了開源的百科系統HDwiki和開源的問答系統Tipask問答系統&#xff0c;蛋痛的這兩套系統均是phpm…