單點登陸通用類

說明

自從上次的《偷懶小工具 - Excel導出》發佈之後,看閱讀量還能夠,就決定繼續分享一下其餘方面的幫助類。html

風格仍是相似的極簡風,登陸方法,調用的代碼儘可能超過三行,而後搞定一切。源代碼參考文章最下方。git


同域和跨域

a.baidu.com 中。a 是二級域名,baidu 是一級域名。一樣的一級域名是能夠共享Cookie的。github

不一樣一級域名,由於同源策略緣由,不能共享Cookie。也就是跨域算法

例如:微信掃碼登陸,就是這種跨域的實用例子跨域

a.baidu.com 和 b.baidu.com 是能夠共享cookie,也就是同域。緩存

www.baidu.com 和 www.qq.com 就屬於跨域。安全

單點登陸

SSO 單點登陸,主要就是使用統一的身份驗證模塊,而後各網站共享身份驗證。微信

也就是隻登陸一次,其餘網站都可免登錄。cookie

關於身份驗證方面,各位若有疑惑可自行百度。或者看一下,我記錄的 《ASP.NET身份認證》函數

(是給本身看的可能有些亂)

由於同源策略的問題,因此同域和跨域方法實現差距比較大。

我這邊根據同域和跨域,這兩種不一樣狀況,分享兩個幫助類。

這兩個幫助類,互相獨立。各位按照本身的需求選擇查看使用。

(由於就一我的精力有限,白天還要上班,沒有進行太多測試)設計不合理或者BUG,確定會有一些。

流程圖

首先,看一下同域的流程圖。

 

再看一下,跨域的流程圖

看着,很簡單吧。我相信大家確定能夠看懂,我就不做解釋了。下面看使用。

使用步驟

配置

這裏WebConfig,採用了以下的配置。

WebConfig

用戶認證網站,直接使用~/Login.aspx 指向本身的登陸頁面。

其餘網站,使用 「認證網站地址」+?link+「本網站地址」。這種方式,來進行登陸後的跳轉。

同域

共同一級域名的狀況。可使用SSOGeneralSameDomain類,進行登陸。

  1. 首先,須要你自行製做一個登陸界面,自行進行用戶名和密碼的驗證
  2. 調用以下方法。
MVC登陸

其中,Login就是用戶登陸方法。一共兩行代碼。name 參數是你須要保存的數據。

其中,Index方法,能夠得到你保存的用戶名。(這裏爲了方便使用的明文用戶名)

WebForm登陸

WebForm登陸方式是同樣的,這裏不作過多描述。

調用 SSOGeneralSameDomain.LogUp(); 可進行用戶註銷。

此時你的網站,就能夠共享身份驗證了。

跨域

不一樣一級域名的狀況。可使用SSOGeneralCrossDomain類,進行登陸

  1. 首先,須要自行製做一個登陸界面。這個無法省略,或者你直接用我示例代碼的登陸。
  2. 認證網站,調用LogIn方法。其餘網站,調用LogInClient方法。
認證網站登陸

須要傳遞:保存的數據、Cookie名稱、保存時長

其餘網站登陸

須要傳遞:認證網站地址、Cookie名稱、保存時長

此時,你就能夠完成跨域單點登陸了。可是注意,認證網站,還須要調用一個驗證方法。

驗證方法

思路和過程

同域 

分析

同域的思路比較簡單,也相對來講比較好實現。有兩點要考慮的(若是有其餘辦法,請留言

  1. Request 和 Response 的操做問題
  2. 其餘網站的登陸後跳轉問題

Request 操做:由於Mvc和WebForm的Request,存在於兩個不一樣的類(HttpContextBase和Page)。

  這個找了半天,也沒有想到能公用的辦法,因而就用抽象工廠來搞了一下。

跳轉問題:由於Forms身份認證的ReturnUrl參數,只能拿到文件,而不能拿到網址。因此無法跳轉到對應網站。

  這個我在博問上試着問了一下,結果有一個大哥說:你要這麼多幹啥,沒啥用。當時我就懵逼了!!!

     後來,沒有找到什麼好辦法,就用的笨辦法,也就是使用link進行跳轉。

作法

這兩個問題解決了,咱們接下來看看代碼。仍是向上次同樣,一步一步來講一下。

作Request和Response操做封裝

首先,建立一個抽象類,而後把須要的方法封裝一下,接着定義Page和HttpContext兩個子類,繼承實現

Operation
OperationHttpContext
OperationPage

作同域單點登陸的類

1. 首先,分析一下每一個登陸,都須要名字和過時時間,那麼這倆字段上移。 確定都得有登陸方法,那麼方法上移。

SSOGeneral

這裏字段Set 私有,也是安全性的考慮。我在初始化的時候,就傳遞這兩個參數。 

2. 接着,建立 SSOGeneralSameDomain 類,繼承抽象類。

定義私有字段,Operation用來執行操做。構造函數中對這個字段進行賦值。

構造函數

實現抽象類的LogIn方法。這個方法只有三步:1.建立Forms認證票據。2.保存到Cookie中。3.成功後跳轉。

Login
Create

CreateTicket 和 CreateCookie 方法邏輯很是簡單,我就不說明了。說一下跳轉邏輯。 

RedirectPage

有link 找link,沒有找ReturnUrl,再沒有直接跳轉到根目錄。 至此登陸作完了。

3. 最後,作註銷和獲取內容方法。這邊爲了方便,使用靜態類實現的。

註銷都是固定的方法,獲取內容,就是拿Cookies。而後解密

Static

同域的幫助類,至此就算完成了。

跨域

跨域真的是比較糾結的一點,由於我懶,因此通常都是先上網找相關文章。

發現,文章有用的很是少。一些僞跨域的特別多,有些卡卡卡說一大堆,結果發現不一樣的是二級域名。

還有就是使用 接口,來回傳信息的。由於我想作幫助類,用接口的話就耦合在一塊兒了。不太想用。

PS:找了一天,最後煩躁了不找了,開始本身想本身研究。

分析

實際上同域須要處理的地方,就是傳遞憑證。接收到憑證之後,就會進行本地存儲,因此傳遞是終點。

跨域須要考慮的點,就比較多了,除了同域的問題還有如下幾點:(若是有其餘辦法,請留言

  1. Cookie不能共享,如何驗證信息
  2. 如何處理登陸用戶的持久化
  3. 登陸和認證要用什麼形式展示

Cookie不能共享:使用Token做爲憑據傳遞,可根據Token獲取保存信息。

持久化:提供持久化接口,任何方式只要知足此接口便可。我這裏提供了Http緩存和Cookies方法。

登陸和認證:流程跟上面的圖差很少。主要開放五個方法:

LogIn(登陸)、LogInClient(其餘網站登陸)、ValidationToken(認證)、GetUserData(獲取登陸內容)、LogUp(註銷)

作法

1. 首先,仍是跟同域同樣作Operation 而後Page 和 HttpContextBase繼承這個Operation

Operation
OperationPage
OperationHttpContext

2. 由於會有憑證的傳遞,因此咱們還須要一個加密。這裏,我給出一個接口,並給出了DES加密的實現方法。

  各位能夠按照本身想進行的加密邏輯,自行擴展。

IOperationSecret
OperationSecret

3. 持久層也是必不可少的,用來存放已經登陸的用戶信息。這裏也是給出的接口。並給出了Cookie 和 Cache的操做方法

  各位能夠按照本身想實現的持久層,進行處理。

IOperationToken
OperationCookies

CreateToken 生成憑證的這個方法。我這邊採用最簡單的GUID進行生成的,這種無規律的是沒有辦法僞造的。

SetToken的UserData,使用的就是上方的加密認證。

我以爲只要涉及到HTTP傳遞,就確定能攔截,因此重點應該是怎麼不讓他破解。加密算法,各位能夠自行實現。

OperationCache
public class SSOToken
    {
        public string UserData { get; set; } public string Token { get; set; } public DateTime OverdueTime { get; set; } }

持久層存儲模型,就使用這個必不可少的幾個字段進行存儲。

4. 跨域單點登陸類,由於這個類比較複雜,因此我不想提太多公共方法或字段。

SSOGeneral

建立SSOGeneralCrossDomain類,咱們把參數都做爲屬性提出來,而後把接口也進行提取。

構造函數

咱們看一下LogIn 登陸方法是如何實現的。

LogIn

這個方法,是認證中心點擊保存之後執行的方法。

先進行SetToken 把登陸信息存到持久層。而後返回對應的Token。

接着進行GetRedirectUrl。這個方法獲取咱們登陸成功後,將要跳轉的地址。

GetRedirectUrl

接下來的,跟同域的狀況同樣。這裏就很少說了。咱們如今已經實現了,認證中心的登陸。接下來,咱們製做其餘網站的登陸。

其餘網站,使用此功能,也要定義本身的Login.aspx頁面,只是在這個頁面調用這個方法。

LogInClient

咱們先判斷,是登陸仍是認證。好比:咱們沒有登陸,打開網站A,這種狀況就是登陸。網站A登陸後,跳轉到網站B,這種狀況就是認證

IsLogin

接下來咱們驗證Token,這一步很重要。這一步能夠把網站引導到認證中心,或者自動認證。

ValidationToken
  1. 首先,咱們認爲沒有傳遞憑證 就是須要登陸。UserData 是已經認證完畢的內容。
  2. 咱們判斷是否同域,由於Cookie只有在一個域下才能夠調用。
  3. 咱們把當前的地址信息封裝,引導到認證中心進行認證。
  4. 沒有進行驗證的都會在這一步卡住。

接下來,就是顯而易見的 解密、本地存儲了。很簡單很少講了。

GetUserData 和 LogUp。一個是獲取本地Cookie,一個是註銷登陸(跟同域操做同樣)

至此,咱們的單點登陸,所有搞定。接下來,咱們進行測試。

測試

同域

首先,咱們建立兩個認證中心。一個MVC的,一個WebForm的。而後Web建立2個網站,MVC建立1個。用來作跳轉。

Authorize 認證中心,使用的是MVP 的PV模式。首先咱們給Web相關的網站,定義統一的Web.Config

WebConfig

同域狀況下,Web1\2 登陸地址均指向 Authorize

接下來,在登陸後調用方法

Login

咱們在 Web1 裏面寫一下獲取方法 和 註銷

Web1

這個時候,咱們Web1設爲啓動項。而後就能夠測試了。具體頁面,我就不粘貼了。能夠參考下方源碼

跨域

跨域須要在各個應用底下,建立本身的Login.aspx登陸頁面。而後調用這個方法,或者你建立主頁調用同樣。

Web1網站 調用方法以下

Login

加載內容以下

Page_Load

Authorize網站,調用方法以下

認證網站

在Initialize 初始化的時候,添加驗證方法。這樣能夠接受其餘網站發送的驗證請求。

在登陸頁面,直接調用登陸方法便可。

具體測試項目,都在Github上。各位能夠自行下載。 

源碼地址:https://github.com/chenxygx/SSOGeneral

相關文章
相關標籤/搜索