詳解可跨域的單點登錄(SSO)實現(xiàn)方案【附.net代碼】
SSO簡介
定義:
傳統(tǒng)的單站點登錄訪問授權機制是:登錄成功后將用戶信息保存在session中,sessionId保存在cookie中,每次訪問需要登錄訪問的資源(url)時判斷當前session是否為空,為空的話跳轉到登錄界面登錄,不為空的話允許訪問。
單點登錄是一種多站點共享登錄訪問授權機制,訪問用戶只需要在一個站點登錄就可以訪問其它站點需要登錄訪問的資源(url)。用戶在任意一個站點注銷登錄,則其它站點的登錄狀態(tài)也被注銷。簡而言之就是:一處登錄,處處登錄。一處注銷,處處注銷。
應用場景:
當一個網(wǎng)站系統(tǒng)稍微復雜一些的時候,需要對業(yè)務進行拆分,比如一個電商網(wǎng)站,可以將商品搜索、商品詳情、購物車、訂單等拆分成一個個子系統(tǒng),。當一個系統(tǒng)拆分成多個子系統(tǒng)的時候就需要單點登錄來做授權了。
業(yè)務需求:
最近公司因為業(yè)務需要開發(fā)了一些子系統(tǒng)需要和主站進行集成,在網(wǎng)上看了好多單點登錄的教程,綜合各種情況總結出了了下面的單點登錄實現(xiàn)思路。其中用到了輪詢跳轉的思路來解決同時給多個分站寫cookie的問題。如有不妥之處歡迎各位批評指正。
實現(xiàn)功能:
1.可完全跨域
2.url透明(分站跳轉不需要url傳遞token或者ticket)
3.同步注銷
4.一次將cookie寫入到多個分站
效果預覽 :

實現(xiàn)思路
實現(xiàn)難點:
這種方式的難點是:怎么在a.com登錄的時候將cookie同時寫到b.com中。我使用的方式是現(xiàn)在sso.com中維護一個分站集合,在登錄成功后以輪詢跳轉的方式將cookie寫到各個分站中。
具體思路:
1.第一次訪問a.com-> 點擊a.com頁面的登錄按鈕->跳轉到sso.com進行登錄驗證->登錄成功后將數(shù)據(jù)存到cache中->然后以輪詢跳轉的方式依次訪問各個分站并將cookie寫到各個分站->最后跳轉到登錄來源頁面
2.登錄成功后->訪問需要登錄的資源(url)->后臺發(fā)送請求到sso.com進行cookie有效性驗證->驗證通過訪問資源
代碼分析
1.新建三個站點:a.com,b.com,sso.com

2.在a.com中新建home/index頁面,如下:
第一次訪問cookie不存在,當以模擬請求的方式到sso.com/login/validateLogin進行驗證的時候返回error,頁面顯示未登錄狀態(tài)
對應的view頁面如下:
sso.com/login/validateLogin對應的代碼:
3.在a.com的首頁點擊登錄按鈕跳轉到sso.com的登錄頁面(login/index)


4.sso.com中的登錄代碼如下:

5.點擊登錄進入到登錄驗證方法
生成token,同時將用戶信息以token為鍵保存在cache中并設置過期時間
獲取分站集合,以重定向輪詢的方式依次向每個分站寫cookie,最后重定向到登錄來源頁面
登錄驗證方法如下:
a.com和b.com中的跳轉寫cookie的方法代碼如下:
/// <summary>
/// 用跳轉的方式寫cookie
/// </summary>
/// <param name="token">授權驗證的令牌</param>
/// <param name="others">一系列分站</param>
/// <param name="main">登錄成功返回的站點</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);//跳轉到登錄來源頁面
}
}
6.返回登錄來源頁面a.com/home/index或者b.com/home/index
此時a.com和b.com已經(jīng)都有cookie
7.登出(退出登錄)的處理
登出直接調(diào)用sso.com/login/LoginOut方法,如下:
總結
這種將用戶登錄信息以cache的方式存放在sso.com,并且將cache的鍵當做cookie的值保存在各個分站的方式實現(xiàn)了跨域單點登錄
這種方式的難點是:怎么在a.com登錄的時候將cookie同時寫到b.com中。我使用的方式是現(xiàn)在sso.com中維護一個分站集合,在登錄成功后以輪詢跳轉的方式將cookie寫到各個分站中。
這種方式在實現(xiàn)跨域單點登錄的同時也存在一些問題:
1.沒有考慮ajax登錄的情況
2.沒有進行各種安全性驗證(IP信任、cookie劫持、暴力登錄……)
考慮不足之處,真誠的希望大家可以提出好的想法以及補充的意見
DEMO下載:demo
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
微信公眾平臺開發(fā)之發(fā)送文本消息.Net代碼解析
這篇文章主要為大家詳細解析了微信公眾平臺開發(fā)之發(fā)送文本消息.Net代碼,感興趣的小伙伴們可以參考一下2016-06-06
asp.net core下給網(wǎng)站做安全設置的方法詳解
這篇文章主要給大家介紹了關于asp.net core下給網(wǎng)站做安全設置的相關資料,文章通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-07-07
asp.net中如何批量導出access某表內(nèi)容到word文檔
最近有項目需求是這樣的,需要將某表中的每一條記錄中的某些內(nèi)容導出在一個word文檔中。下面小編就把我的解決辦法分享給大家,供大家參考2015-10-10
ASP.net Substitution 頁面緩存而部分不緩存的實現(xiàn)方法
在ASP.NET中要實現(xiàn)部分內(nèi)容非緩存,而其它的都需要緩存輸出,可以使用Substitution控件實現(xiàn).2009-03-03
ASP.NET MVC HttpPostedFileBase文件上傳的實例代碼
這篇文章主要介紹了ASP.NET MVC HttpPostedFileBase文件上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07

