1. 程式人生 > >臨近年關,修復ASPNETCore因瀏覽器核心版本引發的單點登陸故障

臨近年關,修復ASPNETCore因瀏覽器核心版本引發的單點登陸故障

臨近年關,諮詢師提出360,搜狗急速瀏覽器無法單點登陸到公司核心產品WD, 報重定向過多。

現象

經過測試, 出現單點登陸故障的是搜狗,360等主打雙核(預設Chrome核心)的瀏覽器, 較新式的Edge,Chrome,Firefox均沒有出現此障礙。

Developer Tool監測不到真實的單點登陸請求,拿出我們CTRL+C,CTRL+V 工程師的底氣,將現象拷貝到網際網路。

同類型問題不少,答案慘不忍睹,味同嚼蠟,人云亦云。年末不能晚節不保,決定啃下這個硬骨頭。

拿出網路分析利器Fiddler:

 

為什麼發生迴圈重定向?

 顯示單點登陸從 認證伺服器重定向回站點website1.com時, 確實發生了迴圈重定向, 搜狗瀏覽器做了重定向次數限制,最終返回瀏覽器定製的404 頁面。

結合之前寫的單點登陸原理:

分析站點發生迴圈重定向的原因:

以上第⑥步,website1向瀏覽器寫入Cookie for website1之後,重定向至業務主頁www.website1.com (第7步)的時候,並未帶上 cookie forwebsite1, 

導致website1 又認為使用者未登陸,申請重定向回 sso-website.com?service=http://www.website1.com (以上第②步);

因為在sso-website.com站點監測到Cookie for sso,開始走④⑤⑥⑦步驟,在第⑦步又沒找到 Cookie for website1,又再次重定向回 sso-website.com?service=http:///www.website1.com.

迴圈往復。

 

定位問題

問題的核心在於最後一步重定向回首頁的時候,沒有帶上該Cookie for website1 。

下面是⑥----> ⑦步驟中,丟失Cookie for website1 的截圖:

熟稔web開發的都知道 Cookie for website1 會在請求 website1.com時自然帶上 

Set-Cookie: X-Gridsum-FullTicketId=TGT-178876-em4uf0faD1c4pbt*********k5Z0vN4uPOoEBWfGIP6l-x-gridsumdissector; path=/; samesite=none; httponly

著重分析 Cookie for website1的附加屬性:

Path 指示需要傳送該cookie頭的根url,      =/ 表現站點下所有地址都會發送該Cookie

SameSite 設定該Cookie的同源策略, = none 指示客戶端應該禁用Cookie 的同源限制

HttpOnly 指示建立的Cookie是否能通過Javascript訪問(這個cookie依然存在與瀏覽器上), 這裡是true,表示不能通過Javascript訪問該Cookie

以上解釋看,附加屬性無懈可擊,理論上能確保 請求website1.com時能載入 Cookie for website1.

最後在官方站點搜到這樣內容:

The SameSite = None parameter causes compatibility problems with clients that implemented the prior 2016 draft standard (for example, iOS 12). See Supporting older browsers in this document;

Apps accessed from older browsers which support the 2016 SameSite standard may break when they get a SameSite property with a value of None. Web apps must implement browser detection if they intend to support older browsers

#  實現IETF 2016草案的客戶端 不認識 Samesite= None屬性值,會有相容性問題, 若站點打算支援這些舊核心瀏覽器就必須實現瀏覽器嗅探。

這個答案讓我眼前一亮,趕緊對比了一下我們出故障的瀏覽器核心:

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0

搜狗瀏覽器的Chrome核心版本65 正處於不相容的列表中,binggo, 問題定位。

 

修復策略

我們的目的是為支援這些舊核心瀏覽器, 但是本人不打算實現瀏覽器嗅探(其實就是根據User-Agent,遮蔽SameSite=none )。

 context.Response.Cookies.Append(_options.SsoTgtName, tgt1, new Microsoft.AspNetCore.Http.CookieOptions
                        {
                            HttpOnly = true,
                            SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None,
                            Secure = false,
                        });

 

結合站點的 同源限制的現狀 , 本站點沒有必要顯式設定 SameSite= None, 可保持Samesite預設值 Lax。

說幹就幹,修改SameSite屬性值,重新k8s部署之後,搜狗瀏覽器正常單點登陸。

 

SameSite 歷史和版本變更

ASP.NETCore 首次支援SameSite 是在2.0 版本實現的(IETF 2016 草案),ASP.NET Core預設將Cookie SameSite設為Lax, 直到在網際網路上遇到很多認證問題。

IETF 2019標準給出了修復補丁, 2019 SameSite 草案規定:

  • 與2016年草案不向後相容
  • 預設將Cookie SameSite= Lax
  • 顯式設定 SameSite= None時,必須將該Cookie 標記為Secure, None 是一個新值
  • ASP.NET Core 3.1 在SameSite列舉值中新增  Unspecified, 表示不寫入SameSite屬性值,繼承瀏覽器預設的Cookie策略
  • 預定於2020年2月由Chrome預設啟用該草案,瀏覽器需要漸漸遷移到 該草案。

 綜上,SameSite=None 引出了一個難纏的瀏覽器新舊版本相容問題,就本站而言,最後一步同域名重定向將 Cookie SameSite=Lax是可行的

+ https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-2.1#sob

+ https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/ 

&n