日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于IdentityServer4的OIDC实现单点登录(SSO)原理简析

發布時間:2023/12/4 编程问答 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于IdentityServer4的OIDC实现单点登录(SSO)原理简析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.



# 寫在前面

IdentityServer4的學習斷斷續續,兜兜轉轉,走了不少彎路,也花了不少時間。可能是因為沒有閱讀源碼,也沒有特別系統的學習資料,相關文章很多園子里的大佬都有涉及,有系列文章,比如:

曉晨大佬的:

https://www.cnblogs.com/stulzq/p/8119928.html

蟋蟀?大佬的:
https://www.cnblogs.com/xishuai/tag/[34]%E5%B0%8F%E8%8F%9C%E5%AD%A6%E4%B9%A0%E7%BC%96%E7%A8%8B-IdentityServer4/

李念輝、楊旭大佬均有相關文章,翻翻便可找到,就不一一列舉了。

但是,不知大家有沒有體會,好像看了很多id4(IdentityServer4,下同)的文章,對:

  • oidc究竟是個什么蛤蟆?

  • OAuth2.0和OpenId Connect究竟有啥區別?

  • id4切確是什么東西?

  • id4能干些啥?

  • id4為什么這么設計?

  • id4各授權流程的區別是啥?

  • id4的SSO是基于什么原理?

我還是時不時:

老實說,這些問題我也一懂半懂,還有就是看多了、時間跨度大,有的以為懂了提筆又忘了。這時大佬肯定說:

”誰叫你不去看源碼?“

我默默的留下了兩行老淚:馬上看,馬上看。

但是我覺得id4很多新手和我一樣都有這困擾,上手門檻確實有的高。誠然看源碼是個不錯的學習方法,但上來就讓新人或使用者看源碼,無疑很不利于推廣、直接勸退啊,畢竟大部分都是跟我一樣的菜逼(對不起拖后腿了)。

對應前面提到的一串問題,我不打算在本文一一解答,我今天著重想聊的是:

id4的SSO是基于什么原理?

寫本文的初衷是看到李念輝大佬的https://www.cnblogs.com/linianhui/p/oidc-in-action-sso.html,所以本文算算是讀博筆記。

啥是SSO?

SSO,全稱Single sign-on :在多個應用系統中,只需要登錄一次,就可以訪問其他相互信任的應用系統。

比如你登錄京東后查看我的訂單:https://order.jd.com 然后再去查看購物車https://cart.jd.com/cart.action就不需要重新登錄。雖然這里頂級域名一致,但其實單點登錄并沒有此要求。

單點登錄,很容易望文生義,以為單點登錄就是限制用戶只能在一處登錄。

下面我們說說我們我們常用的SSO的常用的實現方式。

SSO—基于Cookie的實現簡析

這種方式比較簡單,使用也比較廣泛。

比如我有兩個系統:a.example.com 和 b.example.com,很簡單,只需要搞個 passport.example.com 登錄成功后往:example.com 這個頂級域寫登錄成功的cookie就行了。而后不管你是c.example.com還是d.example.com或是+∞.example.com都只需要驗證登錄的cookie就行,簡單方便。

不過這種實現方式有個比較大的缺陷:

不能跨域,不能跨頂級的域。

我不能說我登錄成功后往jd.com域名下寫cookie吧。還有就是每個業務域名都要做登錄cookie的校驗邏輯 ,不過這算小問題。

既然存在問題,就解決問題吧(這實在沒辦法解決發現問題的人啊)

SSO—基于CAS流程實現簡析

CAS簡介

Central Authentication Service,簡稱:CAS, 是一個單點登錄框架或者說解決方案,開始是由耶魯大學的一個組織開發,后來歸到apereo管理。同時CAS也是開源的,遵循apache 2.0協議,目前代碼放在github上:https://github.com/apereo/cas

打開就驚呆了,看到吧,一堆開源項目在用,這logo閃瞎我的鈦合金狗眼了

我們看下github簡介:

”CAS是一個企業級的、與語言無光的Web SSO解決方案,同時也嘗試整合授權和鑒權的需求。“

既然它是一個解決方案,那我們看看它到底提出了啥。

CAS的方案泳道圖分析

CAS SSO標準流程,看圖說話吧。

右鍵可看查原圖

我們看看發生了啥:

站點App1

  • 用戶首次訪問web App1,App1發現用戶未登錄,攜帶目前訪問地址302到CAS Server登錄頁。

  • CAS Server登錄頁檢查登錄Session不存在,返回一個登錄頁面。

  • 填寫賬號,點擊登錄。

  • CAS Server驗證賬號信息成功,創建一個Ticket Granting Ticket(TGT),這個TGT就是當前登錄用戶的session key。同時,創建一個service ticket并攜帶service ticket key,st key 作為參數跳轉回App1。

  • App1用get發送st key 去CAS Server驗證,驗證通過后返回登錄用戶信息。

  • App1使用返回的登錄用戶信息構建當前系統的登錄狀態,并用一個JSESSIONID標記(JSESSIONID是Apache的默認名),并攜帶這個JSESSIONID重新訪問App1。

  • App1驗證JSESSIONID,登錄成功,展示登錄成功頁面。

  • 第二次訪問,驗證JSESSIONID,直接訪問。

  • 站點App2

  • 用戶首次訪問web App2,App2發現用戶未登錄,攜帶目前訪問地址302到CAS Server登錄頁。

  • CAS Server登錄頁攜帶有App1生成的TGT,那么直接做TCT的驗證,驗證成功不需要登錄,創建一個App2的st key,302回App2。

  • 后續和以上的5,6,7,8 補邏輯相同,不贅述。

  • CAS的流程大概于此,實際的實現可能會復雜一點,可能會遇到各式各樣的問題。但有理論支撐,總體實現起來還是簡單,可靠有保證的。

    下面說說基于Id4的OIDC是怎么做單點登錄的。

    SSO—基于Id4的OIDC實現簡析

    先準備環境

    把官方samples下下來:https://github.com/IdentityServer/IdentityServer4/tree/master/samples

    我刪掉了其他項目,剩下這兩個,一目了然:

    分別把這兩個站點部署為:

    http://odic.server.net

    http://sso.client.net

    我們再看一眼Idoc服務端配置:

    配置IdentityServer,Configs添加這么一個客戶端:

    // sso implicit client new Client {ClientId = "ssoimplicit", //這個client id 跟 MfcImplicit 里面的配置要一致ClientName = "sso implicit clinet",AllowedGrantTypes = GrantTypes.Implicit,RedirectUris = { "http://sso.client.net/signin-oidc" },PostLogoutRedirectUris = { "http://sso.client.net/signout-callback-oidc" },AllowedScopes = new List<string>{IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,IdentityServerConstants.StandardScopes.Email} }

    ok,我們用下抓包工具觀察下登錄流程。

    1、受保護客戶端頁面的訪問

    sso.client.net是客戶端,而登錄頁在sso.client.net服務端

    我們先打開需要登錄才可以訪問的:http://sso.client.net/Home/Secure

    這里302到了授權端點?http://odic.server.net/connect/authorize

    2、授權端點對客戶端請求的驗證

    這就是步驟1中, 302挑戰的授權端點攜帶的參數。

    我們先看看這些參數

    client_id:ssoimplicit //我們前面配置的clinenid=
    reponse_mode:form_post //指示oidc服務器返回數據的形式是form表單
    response_type:id_token //區別于oauth2授權請求的一點,必須包含有id_token這一項。
    scope:openid profile //區別于oauth2授權請求的一點,必須包含有openid這一項。
    state:oauth2定義的一個狀態字符串,這里的實現是加密保存了一些客戶端的信息,讓你最后可以在登錄成功后帶回到客戶端,這個參數聽重要的
    nonce:上一步中寫入cookie的值,這字符串將來會包含在idtoken中原樣返回給客戶端,做安全校驗用。
    redirect_uri:http://sso.client.net/signin-oidc?//認證成功后的回調地址,就是我們配置里面的

    授權端點有很多功能,這里主要做了兩件事:

  • 先判斷待過來的參數是否合法,比如clientid是不是配置里面的,參數有沒有按要求、規范傳過來,參數是否被篡改,未驗證通過會報錯。

  • 授權與否的校驗,根據攜帶的參數,判斷如果登錄,就直接回調 redirect_uri參數地址:http://sso.client.net/signin-oidc,否,302到登錄頁,引導用戶登錄。

  • 3、登錄

    初次登錄,步驟2中的授權端點判斷當前未登錄,還是302,跳轉登錄頁,引導用戶登錄授權。

    點擊登錄,跳轉到是否授權頁面,這個頁面不一定展示,可通過配置Client的RequireConsent=false,跳過這個頁面。

    of course Yes!

    4、登錄成功,客戶端構建登錄狀態

    我們看看點Yes Alow 之后的請求。

    可以清楚的看到去到了:

    http://odic.server.net/connect/authorize/callback

    callback,哦,這是一個登錄回調,它干了啥呢,我們仔細看響應:

    哦,它這里響應回了一個頁面,這個頁面只有一個表單,當頁面一加載完成立刻post表單到:action=’http://sso.client.net/signin-oidc‘ 這個地址。并且仔細看看表單的參數,前面的那些scope、state啊這些參數全都帶了過來,有意思,沒錯,這精妙的設計也是規范之一。

    這里它為什么不帶上clientid呢?哈哈,客戶端自己肯定知道自己的clientid的,另外,還有中間這一大串的id_token你忘了嗎,這里面可是可以攜帶信息的哦。

    來,我們看看這個id_token究竟是何方妖孽。

    我們看到id_token帶有登錄用戶的信息:

    iss:token發放的服務器地址

    aud:clientid

    sid:會話信息

    kid:當前token的標識符

    name:用戶名

    此外還有比如id_token的發放時間,過期時間,nonce,用戶非機密信息等等。還有藍色部分需要使用客戶端公鑰驗證的簽名等等。

    這個時候客戶端已經拿到登錄用戶的信息了,這時客戶端直接使用登錄用戶信息,構建當前應用sso.client.net的登錄狀態即可。

    比如下面的這個 Set名為Implicit的Cookie:

    這個Cookie是可以刪掉的,它本身只維持了在sso.client.net的登錄狀態而已,如果你刪掉它,它就會重新跑到授權端點:http://odic.server.net/connect/authorize 去驗證一下,發現當前會話還是處于登錄狀態的,然后又302到登錄回調地址http://sso.client.net/signin-oidc,然后/signin-oidc從state參數里面取出redirect_url,302回到當前頁面。

    最后我們來看一下登錄成功的頁面

    單點登出

    單點登出我就不細說了,使用:

    //指定登錄方案的方式登出 await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);//或者直接 await HttpContext.SignOutAsync();暴力點刪除cookie也可以,不過那只能算是半退出狀態吧。

    總結

    通過對以上一個使用Id4構建的OIDC實現的登錄流程來看,OIDC的SSO它完全無光域名的,id4登錄成功后,客戶端通過使用id_token來構建自身的登錄狀態,一個client如此,N個皆然。

    大家好像感覺這個SSO的實現方式跟前面的CAS流程很像誒,我們再看一遍前面CAS的圖

    好像是發現了啥不得了的東西。

    沒錯:openid也是基于CAS流程的一個實現(我根據理解猜的 沒有證據)。

    再多說兩句

    id4確實是好東西,暫時用不上也要多了解、學習,最好寫個博客做個筆記加深下理解。

    在理解的基礎上不要去背各種Flow有啥區別什么的,知道什么場景下用那種流程就行,也沒幾個。

    善用官方文檔、Sample。

    本文示例源碼

    https://github.com/gebiWangshushu/cnblogs-demos

    參考

    https://yq.aliyun.com/articles/636281

    https://www.cnblogs.com/linianhui/p/oidc-in-action-sso.html

    文章博客園地址請點擊“閱讀原文”

    總結

    以上是生活随笔為你收集整理的基于IdentityServer4的OIDC实现单点登录(SSO)原理简析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。