詳解可跨域的單點(diǎn)登錄(SSO)實(shí)現(xiàn)方案【附.net代碼】
SSO簡介
定義:
傳統(tǒng)的單站點(diǎn)登錄訪問授權(quán)機(jī)制是:登錄成功后將用戶信息保存在session中,sessionId保存在cookie中,每次訪問需要登錄訪問的資源(url)時(shí)判斷當(dāng)前session是否為空,為空的話跳轉(zhuǎn)到登錄界面登錄,不為空的話允許訪問。
單點(diǎn)登錄是一種多站點(diǎn)共享登錄訪問授權(quán)機(jī)制,訪問用戶只需要在一個(gè)站點(diǎn)登錄就可以訪問其它站點(diǎn)需要登錄訪問的資源(url)。用戶在任意一個(gè)站點(diǎn)注銷登錄,則其它站點(diǎn)的登錄狀態(tài)也被注銷。簡而言之就是:一處登錄,處處登錄。一處注銷,處處注銷。
應(yīng)用場景:
當(dāng)一個(gè)網(wǎng)站系統(tǒng)稍微復(fù)雜一些的時(shí)候,需要對業(yè)務(wù)進(jìn)行拆分,比如一個(gè)電商網(wǎng)站,可以將商品搜索、商品詳情、購物車、訂單等拆分成一個(gè)個(gè)子系統(tǒng),。當(dāng)一個(gè)系統(tǒng)拆分成多個(gè)子系統(tǒng)的時(shí)候就需要單點(diǎn)登錄來做授權(quán)了。
業(yè)務(wù)需求:
最近公司因?yàn)闃I(yè)務(wù)需要開發(fā)了一些子系統(tǒng)需要和主站進(jìn)行集成,在網(wǎng)上看了好多單點(diǎn)登錄的教程,綜合各種情況總結(jié)出了了下面的單點(diǎn)登錄實(shí)現(xiàn)思路。其中用到了輪詢跳轉(zhuǎn)的思路來解決同時(shí)給多個(gè)分站寫cookie的問題。如有不妥之處歡迎各位批評指正。
實(shí)現(xiàn)功能:
1.可完全跨域
2.url透明(分站跳轉(zhuǎn)不需要url傳遞token或者ticket)
3.同步注銷
4.一次將cookie寫入到多個(gè)分站
效果預(yù)覽 :
實(shí)現(xiàn)思路
實(shí)現(xiàn)難點(diǎn):
這種方式的難點(diǎn)是:怎么在a.com登錄的時(shí)候?qū)ookie同時(shí)寫到b.com中。我使用的方式是現(xiàn)在sso.com中維護(hù)一個(gè)分站集合,在登錄成功后以輪詢跳轉(zhuǎn)的方式將cookie寫到各個(gè)分站中。
具體思路:
1.第一次訪問a.com-> 點(diǎn)擊a.com頁面的登錄按鈕->跳轉(zhuǎn)到sso.com進(jìn)行登錄驗(yàn)證->登錄成功后將數(shù)據(jù)存到cache中->然后以輪詢跳轉(zhuǎn)的方式依次訪問各個(gè)分站并將cookie寫到各個(gè)分站->最后跳轉(zhuǎn)到登錄來源頁面
2.登錄成功后->訪問需要登錄的資源(url)->后臺(tái)發(fā)送請求到sso.com進(jìn)行cookie有效性驗(yàn)證->驗(yàn)證通過訪問資源
代碼分析
1.新建三個(gè)站點(diǎn):a.com,b.com,sso.com
2.在a.com中新建home/index頁面,如下:
第一次訪問cookie不存在,當(dāng)以模擬請求的方式到sso.com/login/validateLogin進(jìn)行驗(yàn)證的時(shí)候返回error,頁面顯示未登錄狀態(tài)
對應(yīng)的view頁面如下:
sso.com/login/validateLogin對應(yīng)的代碼:
3.在a.com的首頁點(diǎn)擊登錄按鈕跳轉(zhuǎn)到sso.com的登錄頁面(login/index)
4.sso.com中的登錄代碼如下:
5.點(diǎn)擊登錄進(jìn)入到登錄驗(yàn)證方法
生成token,同時(shí)將用戶信息以token為鍵保存在cache中并設(shè)置過期時(shí)間
獲取分站集合,以重定向輪詢的方式依次向每個(gè)分站寫cookie,最后重定向到登錄來源頁面
登錄驗(yàn)證方法如下:
a.com和b.com中的跳轉(zhuǎn)寫cookie的方法代碼如下:
/// <summary> /// 用跳轉(zhuǎn)的方式寫cookie /// </summary> /// <param name="token">授權(quán)驗(yàn)證的令牌</param> /// <param name="others">一系列分站</param> /// <param name="main">登錄成功返回的站點(diǎn)</param> /// <returns></returns> public ActionResult Jump(string token, string others, string main) { HttpCookie cookie = new HttpCookie("currentUser"); cookie.HttpOnly = true; cookie.Expires = DateTime.Now.AddYears(100);//永不過期 cookie.Value = token; Response.Cookies.Add(cookie); //依次減掉已經(jīng)寫過cookie的分站 if (!string.IsNullOrEmpty(others)) { //獲取分站集合 var substationList = others.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (substationList.Count == 1) { return Redirect(others + "&main=" + main); } else { string currentRedirect = substationList[0]; substationList.RemoveAt(0); string otherss = string.Join(",", substationList); return Redirect(currentRedirect + "&others=" + otherss + "&main=" + main); } } else { return Redirect(main);//跳轉(zhuǎn)到登錄來源頁面 } }
6.返回登錄來源頁面a.com/home/index或者b.com/home/index
此時(shí)a.com和b.com已經(jīng)都有cookie
7.登出(退出登錄)的處理
登出直接調(diào)用sso.com/login/LoginOut方法,如下:
總結(jié)
這種將用戶登錄信息以cache的方式存放在sso.com,并且將cache的鍵當(dāng)做cookie的值保存在各個(gè)分站的方式實(shí)現(xiàn)了跨域單點(diǎn)登錄
這種方式的難點(diǎn)是:怎么在a.com登錄的時(shí)候?qū)ookie同時(shí)寫到b.com中。我使用的方式是現(xiàn)在sso.com中維護(hù)一個(gè)分站集合,在登錄成功后以輪詢跳轉(zhuǎn)的方式將cookie寫到各個(gè)分站中。
這種方式在實(shí)現(xiàn)跨域單點(diǎn)登錄的同時(shí)也存在一些問題:
1.沒有考慮ajax登錄的情況
2.沒有進(jìn)行各種安全性驗(yàn)證(IP信任、cookie劫持、暴力登錄……)
考慮不足之處,真誠的希望大家可以提出好的想法以及補(bǔ)充的意見
DEMO下載:demo
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
ASP.NET Core使用SkiaSharp實(shí)現(xiàn)驗(yàn)證碼的示例代碼
本篇文章主要介紹了ASP.NET Core使用SkiaSharp實(shí)現(xiàn)驗(yàn)證碼的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12ASP.NET MVC 4 中的JSON數(shù)據(jù)交互的方法
本篇文章主要介紹了ASP.NET MVC 4 中的JSON數(shù)據(jù)交互的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04ASP.NET Core中間件初始化的實(shí)現(xiàn)
在日常使用ASP.NET Core開發(fā)的過程中我們多多少少會(huì)設(shè)計(jì)到使用中間件的場景,本文探究了ASP.NET Core中間件是如何初始化的,感興趣的可以了解一下2021-05-05ASP.NET批量操作基于原生html標(biāo)簽的無序列表的三種方法
無序列表被大量使用,ASP.NET雖然內(nèi)置了BulletedList控件,用于創(chuàng)建和操作無序列表,但感覺不太好用2014-09-09對ASP.Net的WebAPI項(xiàng)目進(jìn)行測試
這篇文章介紹了對WebAPI項(xiàng)目進(jìn)行測試的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04