91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringSecurity原理解析之如何理解令牌還原與Session

發布時間:2021-10-25 17:20:16 來源:億速云 閱讀:166 作者:iii 欄目:編程語言

本篇內容主要講解“SpringSecurity原理解析之如何理解令牌還原與Session”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“SpringSecurity原理解析之如何理解令牌還原與Session”吧!

SpringSecurity 原理解析【4】:令牌還原與Session

Session:一般稱為會話,不同環境中含義不同,在Spring Security中一個會話指:客戶端從令牌認證請求到登出注銷請求之間的過程。Web應用基本都是基于HTTP協議,而該協議是一個無狀態協議,兩個HTTP請求相互獨立,無法識別對方,在Web應用特別是Spring Security等安全框架中,同一個客戶端發出的多個請求,如果不能識別出,每個請求都需要認證過程,這對于每次請求都需要主動提供身份識別信息的客戶端而言絕對是一個災難。因此需要一個方案來解決這個問題:解決方案整體而言只有一個:就給相關的HTTP請求添加一個全局總線,將這些HTTP請求打上統一標志來說明這些請求都是來自同一個身份。而實現目前主流兩種:Session 和 WebToken,前者為主流標準Web應用總線方案實現,標志打在Cookie或者URL上,后者為主流前后端分離Web應用總線方案實現,標志打在請求頭上。

今天主要說明前者Session。在JavaEE中Session特指HttpSession,其規范是在服務器端定義且實現的:默認每個請求都會具有一個Session實例

public interface HttpSession {
	
	// 創建時間
    long getCreationTime();
	
	boolean isNew();

	// 唯一ID
    String getId();

	// 最近一次訪問時間
    long getLastAccessedTime();

	//Servlet上下文
    ServletContext getServletContext();

	// 具有失效能力
	void invalidate();
	
    void setMaxInactiveInterval(int var1);

    int getMaxInactiveInterval();

	// 具有存儲能力	
    Object getAttribute(String var1);

    Enumeration<String> getAttributeNames();

    void setAttribute(String var1, Object var2);

    void removeAttribute(String var1);

}

此時可以這么理解Session:是一個具有唯一標識且可控生命周期的存儲結構,底層一般為:ConcurrentMap<String, Object>

Session追蹤

會話追蹤: SessionTracking,意思是追蹤Session來源,也就是從哪里開始查找總線標記,默認為Cookie和URL,@since Servlet 3.0可配置

public enum SessionTrackingMode {
    COOKIE, URL, SSL
}

Cookie就是將sessionId寫入Cookie,URL則是在重定向時將sessionId寫入URL。而解析Cookie或者URL是在HttpServer內部完成的,例如:tomcat、undertow。所以一般看不到Session構建的細節(不同服務器實現不一樣),例如Tomcat服務器在構建Request時在CoyoteAdapter#postParseRequest,解析SessionId順序為URL --> Cookie --> SSL ,且Cookie優先級最高,URL次之。

雖然不用知道如何解析Session,但是JavaEE給出構建入口和構建要求:HttpServletRequest#getSession,默認情況下session的構建交給HttpServer完成,但對于分布式應用,可以由Spring Session模塊接手Session的生命周期。

注意如果會話追蹤ID丟失,則會導致Session==null,后續所有依賴了Session存儲的功能就會失敗:例如:CsrfFilter

// 主動確定返回的Session是否需要重新構建
HttpSession getSession(boolean var1);

// 獲取當前請求的Session實例,如果不存在則構建
HttpSession getSession();

// 修改SessionId
String changeSessionId();

// Session有效性:是否存活
boolean isRequestedSessionIdValid();
// Session構建來源:是否從Cookie中解析
boolean isRequestedSessionIdFromCookie();
// Session構建來源:是否從URL中解析
boolean isRequestedSessionIdFromURL();

在Spring Security中在服務端完善令牌之后,可以從上篇文章圖示中看到:令牌完整之后進行了Session、Context和Cookie管理.

Session的處理是通過SessionAuthenticationStrategy來執行的。默認是組合(Composite)策略,內置:ChangeSessionIdAuthenticationStrategy,復用現有Session,修改其唯一標識。

CsrfAuthenticationStrategy (org.springframework.security.web.csrf)
ConcurrentSessionControlAuthenticationStrategy (org.springframework.security.web.authentication.session)
RegisterSessionAuthenticationStrategy (org.springframework.security.web.authentication.session)
CompositeSessionAuthenticationStrategy (org.springframework.security.web.authentication.session)
NullAuthenticatedSessionStrategy (org.springframework.security.web.authentication.session)
AbstractSessionFixationProtectionStrategy (org.springframework.security.web.authentication.session)
    ChangeSessionIdAuthenticationStrategy (org.springframework.security.web.authentication.session)
    SessionFixationProtectionStrategy (org.springframework.security.web.authentication.session)

在Session做了案底之后就可以在后續請求中獲取到并還原了

令牌還原

在Spring Security中有一個優先級很高的過濾器:SecurityContextPersistenceFilter:上下文持久化過濾器,還記得在FilterSecurityInterceptor中獲取服務端完整令牌就是從SecurityContext中獲取的嗎?

SecurityContext contextBeforeChainExecution = securityContextRepository.loadContext(holder);

這里有個SecurityContextRepository,安全上下文存儲庫,默認是HttpSessionSecurityContextRepository,也就是從HttpSession中獲取到的上下文。而HttpSession則在會話追蹤中已經還原了。

// -------------------------------- session 存儲 ------------------------------
// 先獲取到請求中的Session
HttpSession httpSession = request.getSession(false);
// 從Session中獲取SecurityContext
SecurityContext context = readSecurityContextFromSession(httpSession);



// context 就是從ConcurrentMap中 key="SPRING_SECURITY_CONTEXT"獲取
Object contextFromSession = httpSession.getAttribute(springSecurityContextKey);

// -------------------------------- context 存儲 ------------------------------
SecurityContextHolder.setContext(context);

到這里,Session的整體流程就清晰明了了,整體圖示如下:

SpringSecurity原理解析之如何理解令牌還原與Session

Session配置

Session細節交給了服務器去設置,但是Session的配置接口是規范好的:

public interface SessionCookieConfig {
	
	// 名稱配置:常見為:JSESSIONID
    void setName(String var1);

    String getName();

	// 設置能攜帶Cookie的請求域名
	// 后綴匹配,設置格式:點+域名
    void setDomain(String var1);

    String getDomain();

    // 設置能攜帶Cookie的請求路徑
    // 前綴匹配:緊鄰域名之后的部分URL,默認:/
    void setPath(String var1);

    String getPath();

    // 設置額外備注 
    void setComment(String var1);

    String getComment();
	
	// 是否允許客戶端操作Cookie
    void setHttpOnly(boolean var1);

    boolean isHttpOnly();

    // 設置能攜帶Cookie的請求方式:
	// ture: https,false: http、https
    void setSecure(boolean var1);

    boolean isSecure();
	
	// 有效期配置,默認-1,常見:3600
    void setMaxAge(int var1);

    int getMaxAge();
}

Spring對Server的Session有對應的配置類,在容器啟動是會配置到Servlet中。示例:

server.servlet.context-path= /ctx
server.servlet.session.cookie.name= Authorization
server.servlet.session.cookie.path= /ctx/cookie/
server.servlet.session.cookie.max-age=3600
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=false
server.servlet.session.cookie.comment=new cookie name

瀏覽器:

Set-Cookie: Authorization=_xkjjuKHOrOLbS3KRlUmOrRYYn-Z9oa-cLCLWS54; Version=1; Path=/ctx/cookie/; HttpOnly; Max-Age=3600; Expires=Mon, 26-Oct-2020 02:25:57 GMT; Comment="new cookie name"

后續攜帶Cookie

Cookie: Authorization=dhiWDzOksYItVwcqIZAew0YQqtA8BI9DZIVUXWjK

注意:Cookie的path默認為:"/",意味著任何頁面如果攜帶Cookie,將是同一個。如果配置為其他值,一定要保證Spring Security的認證路徑能匹配到來傳輸Cookie。配置格式應該為:"contextPath/匹配值路徑/",表示匹配路徑及其子路徑都會攜帶匹配路徑請求是產生的Cookie。

到此,相信大家對“SpringSecurity原理解析之如何理解令牌還原與Session”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

濮阳县| 富宁县| 泾川县| 皮山县| 长宁县| 大渡口区| 紫金县| 封丘县| 砚山县| 南开区| 临泽县| 惠东县| 桃源县| 拉孜县| 安仁县| 平邑县| 延庆县| 惠来县| 宣汉县| 景谷| 吴忠市| 延庆县| 南阳市| 大名县| 盖州市| 嘉定区| 吉木萨尔县| 崇礼县| 阿巴嘎旗| 永兴县| 泰兴市| 壶关县| 江口县| 大连市| 枣阳市| 和林格尔县| 密云县| 安达市| 宜阳县| 屏东县| 青海省|