IdentityServer4筆記整理(更新中)

来源:https://www.cnblogs.com/Kane-Blake/archive/2019/06/27/11096322.html
-Advertisement-
Play Games

"1 OAuth 2.0" "1.1 OAuth 2.0協議流程圖" "1.2 授權碼模式" "1.3 簡化模式" "2 OpenID Connect(OIDC)" "2.1 OIDC協議流程圖" "2.2 OIDC在OAuth 2.0之上的擴展內容" "3 JSON Web Token" "3.1 ...


博客與筆記無法實時同步, 筆記最新鏈接

OAuth 2.0

定義:OAuth 2.0是一個開放授權標準:允許資源所有者(用戶)授權第三方應用訪問該用戶在某服務上的特定私有資源,但不提供賬號密碼給第三方應用。
安全提示:授權碼和所有令牌必須通過Tsl加密傳輸。進入OAuth 2.0官網

OAuth 2.0協議流程圖

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+
                         (OAuth 2.0協議流程)
    (A)客戶端發起授權請求,客戶端可以向資源所有者直接發起授權請求,建議的做法是將授權伺服器作為中間人,客戶端向授權伺服器發起授權請求
    (B)客戶端收到授權憑證(和具體的授權類型有關)
    (C)客戶端通過授權憑證向授權伺服器請求訪問令牌
    (D)授權伺服器驗證授權憑證和客戶端,如果通過驗證,返回給客戶端訪問令牌
    (E)客戶端通過訪問令牌向資源伺服器發出訪問請求
    (F)資源伺服器驗證訪問令牌有效後,返回請求的資源

授權碼模式

授權碼模式:code的生命周期必須短暫、或者只能單次使用,如果code被多次使用,授權伺服器必須使該code生成的所有令牌失效。訪問令牌由client後端保存。

     +----------+
     | Resource |
     |   Owner  |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier      +---------------+
     |         -+----(A)-- & Redirection URI ---->|               |
     |  User-   |                                 | Authorization |
     |  Agent  -+----(B)-- User authenticates --->|     Server    |
     |          |                                 |               |
     |         -+----(C)-- Authorization Code ---<|               |
     +-|----|---+                                 +---------------+
       |    |                                         ^      v
      (A)  (C)                                        |      |
       |    |                                         |      |
       ^    v                                         |      |
     +---------+                                      |      |
     |         |>---(D)-- Authorization Code ---------'      |
     |  Client |          & Redirection URI                  |
     |         |                                             |
     |         |<---(E)----- Access Token -------------------'
     +---------+       (w/ Optional Refresh Token)
    (A)客戶端引導用戶代理(瀏覽器)到達授權終結點,並攜帶參數:response_type(code)、client_id、redirect_uri、scope、state
    (B)授權伺服器通過用戶代理(瀏覽器)驗證資源所有者,並確定資源所有者是否給予客戶端授權
    (C)驗證資源所有者成功,並且允許授權,授權伺服器將用戶代理(瀏覽器)重定向到redirect_uri,並返回code和授權請求的state
    (D)客戶端向授權伺服器令牌終結點請求令牌,攜帶參數:grant_type、code、redirect_uri、client_id、secret(可選)
    (E)授權伺服器驗證code、client_id、secret是否有效,並驗證redirect_uri是否與步驟C中一致,如果驗證成功,攜帶Access Token將用戶代理(瀏覽器)重定向到redirect_uri

簡化模式

要點:不支持刷新令牌,訪問令牌編碼在Url中,所以會有暴露的風險(在Oauth2.0官網中已經不推薦使用)

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier     +---------------+
     |         -+----(A)-- & Redirection URI --->|               |
     |  User-   |                                | Authorization |
     |  Agent  -|----(B)-- User authenticates -->|     Server    |
     |          |                                |               |
     |          |<---(C)--- Redirection URI ----<|               |
     |          |          with Access Token     +---------------+
     |          |            in Fragment
     |          |                                +---------------+
     |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
     |          |          without Fragment      |     Client    |
     |          |                                |    Resource   |
     |     (F)  |<---(E)------- Script ---------<|               |
     |          |                                +---------------+
     +-|--------+
       |    |
      (A)  (G) Access Token
       |    |
       ^    v
     +---------+
     |         |
     |  Client |
     |         |
     +---------+
    (A)客戶端引導用戶代理(瀏覽器)到達授權終結點,並攜帶參數:response_type(token)、client_id、redirect_uri、scope、state
    (B)授權伺服器通過用戶代理(瀏覽器)驗證資源所有者,並確定資源所有者是否給予客戶端授權
    (C)驗證資源所有者成功,並且允許授權,授權伺服器將用戶代理(瀏覽器)重定向到redirect_uri,redirect_uri的URL 錨點(fragment)部分包括了響應參數(以#hash值的方式追加):access_token、token_type、expires_in、scope、state
    (D)用戶代理(瀏覽器)向redirect_uri發出請求,但不包括URL 錨點,用戶代理在本地保存了fragment。
    (E)redirect_uri的伺服器返回頁面給瀏覽器,該頁面需要包含解碼fragment的腳本。
    (F)瀏覽器接收到頁面後,執行腳本,將C中的響應參數解碼出來
    (G)用戶代理(瀏覽器)將響應參數傳遞給客戶端

OpenID Connect(OIDC)

定義:它在OAuth2上構建了一個身份層,是一個基於OAuth2協議的身份認證標準協議

image

OIDC協議流程圖

+--------+                                   +--------+
|        |                                   |        |
|        |---------(1) AuthN Request-------->|        |
|        |                                   |        |
|        |  +--------+                       |        |
|        |  |        |                       |        |
|        |  |  End-  |<--(2) AuthN & AuthZ-->|        |
|        |  |  User  |                       |        |
|   RP   |  |        |                       |   OP   |
|        |  +--------+                       |        |
|        |                                   |        |
|        |<--------(3) AuthN Response--------|        |
|        |                                   |        |
|        |---------(4) UserInfo Request----->|        |
|        |                                   |        |
|        |<--------(5) UserInfo Response-----|        |
|        |                                   |        |
+--------+                                   +--------+
EU:End User:一個人類用戶。
RP:Relying Party ,用來代指OAuth2中的受信任的客戶端,身份認證和授權信息的消費方;
OP:OpenID Provider,有能力提供EU認證的服務(比如OAuth2中的授權服務),用來為RP提供EU的身份認證信息;
ID Token:JWT格式的數據,包含EU身份認證的信息。
UserInfo Endpoint:用戶信息介面(受OAuth2保護),當RP使用Access Token訪問時,返回授權用戶的信息,此介面必須使用HTTPS。
    (1).RP發送一個認證請求給OP;
    (2).OP對EU進行身份認證,然後提供授權;
    (3).OP把ID Token和Access Token(需要的話)返回給RP;
    (4).RP使用Access Token發送一個請求到UserInfo EndPoint;
    (5).UserInfo EndPoint返回EU的Claims。

OIDC在OAuth之上的擴展

  • [ ] Scope:openid(用來區分這是一個OIDC的Authentication請求,而不是OAuth2的Authorization請求)
  • [ ] response_type:id_token,在implicit模式下請求id_token
  • [ ] id_token:身份令牌,是一個授權伺服器提供的包含用戶信息(由一組Cliams構成以及其他輔助的Cliams)的JWT格式的數據結構
  • [ ] UserInfo Endpoint:通過id_token從用戶信息終結點獲得一組EU相關的Claims,比如可以將Claims從token移除,避免token過大,只保留sub,通過UserInfo Endpoint查詢Claims
"response_type"參數值 OIDC授權類型
code Authorization Code Flow
id_token token Implicit Flow
code id_token Hybrid Flow
  • Authorization Code Flow:從授權終結點返回code,從令牌終結點返回token
  • Implicit Flow:從授權終結點返回所有token
  • Hybrid Flow:id_token返回給前端,access_token在後端保存(access_token的安全性要求比id_token)高

JSON Web Token

定義:JWT是一個定義一種緊湊的,自包含的並且提供防篡改機制的傳遞數據的方式的標準協議

JWT格式

JWT由3部分構成:header.payload.signature
在IdSrv中,payload中的鍵值對根據token類型和授權流程的不同有所區別
header:
{
  "alg": "RS256",//簽名演算法
  "kid": "9dcf733a1192a6da053e64c6ee22ff87",
  "typ": "JWT"//token類型
}
payload://需要傳遞的數據
{
  "nbf": 1556591630,//該jwt在此之前無效
  "exp": 1556595230,//該jwt在此之後無效
  "iss": "http://localhost:7102",//jwt頒發者
  "iat": 1516239022,//jwt頒發時間
  "aud": "http://localhost:7102/resources",//jwt接收者
  "client_id": "jsImplicit",
  "sub": "SubjectId",//用戶唯一id
  "auth_time": 1556591629,//授權時間
  "idp": "local",//identityProvider
  "name": "Username",
  "scope": [
    "openid",
    "profile"
  ],
  "amr": [
    "pwd"//authenticationMethod
  ]
}
signature://token生成方使用私匙生成token,token消費方使用用公匙驗證token是否被修改過
RSASHA256(
  base64UrlEncode(header) + "." +base64UrlEncode(payload),Public Key,Private Key
  )
expires_in="exp"-"nbf"

IdentityServer4

客戶端憑證模式

不支持刷新令牌、無法訪問用戶資源scope(openid、profile、email等)

Request:
    POST /connect/token HTTP/1.1  #請求方式只能為post
    Host: idsrv-server.com
    Content-type: application/x-www-form-urlencoded #參數只能放在body裡面
    body:
    {
        grant_type:client_credentials
        client_id:ClientCredentials
        client_secret:iwiaXNzIjoibnVsbCIsImF1ZCI6WyJudWxsL3Jlc291cmNlcyIsIm9yZGVycyJdLCJjbGllbnRfaWQiOiJDb
        scope:orders openid(可選,預設請求所有scope)
    }
Response:
    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-store
    Pragma: no-cache
     
    {
      "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
      "token_type":"bearer",
      "expires_in":3600
    }

資源所有者密碼模式

用於同一組織下授權

#請求token
Request:
    POST /connect/token HTTP/1.1
    Host: idsrv-server.com
    Content-type: application/x-www-form-urlencoded
    body:
    {
        grant_type:password
        username:dd
        password:dd
        client_id:eshopOnVue
        scope:orders(可選參數)
    }

#請求刷新令牌:原刷新令牌失效、之前頒發的access_token不受影響(需要實現手動失效)
Request:
    POST /connect/token HTTP/1.1
    Host: idsrv-server.com
    Content-type: application/x-www-form-urlencoded
    body:
    {
        grant_type:refresh_token
        refresh_token:e4364377ec69c8d5c06a49d7b74efbd2a29015ac37e9ede8e17597d348931d32
        client_id:eshopOnVue
    }
Respose:
{
    "id_token": "eyJhbGciO.iJSUzI1NiI.sImtpZCw",
    "access_token": "eyJhb.GciOiJSUz.I1NiIsIm",
    "expires_in": 3600,
    "token_type": "Bearer",
    "refresh_token": "60e7dda6e30473ce6dc0a1656b38c174a74ef73310d"
}
#通過access_token請求用戶終結點(需要scope:profile):/connect/userinfo

簡化模式

第三方向授權終結點請求授權,授權成功後,通過Url錨點(#)將access_token、id_token傳給redirecturl

授權碼模式

流程分析

1 IdentityServer服務端啟用服務
2 MVC項目配置OIDC保護控制器,並設置clent_id等
3 webApi項目配置Bearer認證保護Api

1.訪問受IdentityServer OIDC保護的MVC控制器
2.自動重定向到IdentityServer的/connect/authorize,並附帶clint信息

IdSrv授權碼模式:
Js客戶端mgr.signinRedirect()
1.向IdSrv伺服器請求/.well-known/openid-configuration 獲取IdSrv數據
2.向/connect/authorize發起授權請求,攜帶以下參數
client_id: js
redirect_uri:登錄成功後跳轉的地址
response_type: code
scope:請求的資源許可權
state: 2dd196cd7a68402199534d6123791e64
code_challenge: 23kG8msCLc2oHDnTALRTGElqmNAaTADOwUmLMnENFTE
code_challenge_method: S256
3.1.如果驗證client信息正確,且攜帶了idsrv.session和idsrv兩個cookie,並已經授權,則跳轉到redirect_uri,並攜帶以下參數給前端頁面:
code:授權碼
scope:請求的資源許可權
state: a656e5bb62024ee48d8267127e46fa68
session_state: YjwA6dW7trE2II5E0ao6h0y2ty4PoiFrV4qZN0XVjvI.46fe4aa153c9d5480e0f61406e35e5ff
3.1.1、在redirect_uri頁面,通過Oidc.UserManager({ response_mode: "query" }).signinRedirectCallback(),通過授權碼向/connect/token請求token,攜帶以下參數
client_id: js
code: 725ca140eb5afdbc8f37cda96eeb53550aa4502de462c77d0618eed2353422d4
redirect_uri: http://localhost:5003/callback.html
code_verifier: a6ff87be469a4171bf1bfd43e5310468bf1d196d337244e2a829b0e94fe476bb9fdad37d300048e692c2fe58c734b0b6
grant_type: authorization_code
3.1.2將code、token寫入cookie保存,否則下次通過idsrv.session和idsrv兩個cookie申請新的授權碼,同時再次跳轉到初始請求頁面
3.2.如果驗證client信息,但未授權,則跳轉到/Account/Login並攜帶一個ReturnUrl參數
該參數為/connect/authorize/callback並附帶步驟2的所有參數。該參數需要保存併在登錄成功後,跳轉到該頁面
3.3輸入賬號密碼,進入自定義驗證Api中
3.4驗證成功,通過HttpContext.SignInAsync方法為用戶頒發加密的用戶憑證,將idsrv.session和idsrv兩個cookie寫入請求頭
3.5.在自定義Api中跳轉到ReturnUrl
3.6.1如果未配置授權頁面,IdSrv服務端將/connect/authorize/callback重定向到redirect_uri,並攜帶授權碼等參數,重覆3.1.1
3.6.2如果配置了授權頁面,IdSrv服務端將/connect/authorize/callback重定向到授權頁面

登出操作:
Js客戶端mgr.signoutRedirect()
1.向IdSrv請求/connect/endsession 並攜帶以下兩個參數
id_token_hint:
post_logout_redirect_uri: 登出回調地址
2.重定向到/Account/Logout 並攜帶生成的logoutId參數
3.在Logout里清除await HttpContext.SignOutAsync() 並跳轉到post_logout_redirect_uri

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一直用C#開發程式,.NET的功能越來越多,變化也挺大的,從最初的封閉,到現在的開源,功能不斷的增加,一直在進步。作為C#的強烈支持者,C#的變化,我不能不關註,這篇文章主要介紹,C#6.0和C#7.0增加的功能。C#的發展史和.NET以前的版本,請看C#和.NET版本,這邊文章中有介紹。 C# 6 ...
  • 前言:使用winform觸發一個事件後執行的代碼,如果耗時非常長,則會導致視窗界面假死! 本人最近通過winform窗體執行一項:需要批量更新一批資料庫的數據的操作的任務時,由於數據量達到百萬級別,非常耗時,只能慢慢更新,慢慢執行。 但是,在執行的過程遇到了一個奇葩的問題:窗體在調試狀態下,代碼可以 ...
  • 代碼文件:https://github.com/Caijt/CollapsePanel 最近在學習做winform,想實現一個系統導航菜單,系統菜單以模塊進行分組,菜單是樹型結構。 效果類似舊版QQ的那種摺疊面板,就是垂直併排很多個模塊按鈕,按其中一個模塊就展開哪一個模塊裡面樹型菜單,如下圖所示,我 ...
  • 運行環境 操作系統 開發工具 frameworks .Net Core SDK 版本 托管運行 本地 Win10 VS 2015 net461 2.1.401 Kestrel 伺服器 WIn Server 2012 1.0.0-preview2-003121 IIS 開發做瞭如下相關修改: 把 Ap ...
  • 現項目開始全面接入Autofac,但上線了後發現,iis進程被回收後,在訪問網頁提示找不到註冊在Autofac中的類型,或者實例。現在處理辦法記錄如下: 1. IIS托管的應用程式,在首次載入時,所有程式集會被載入到AppDomain中[但AppDomain會被iis回收,且程式集只在被需要的時候進 ...
  • /// <summary> /// load載入數據 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormAdd_Load(object sender, Even ...
  • 最近在使用WPF的時候,遇到某個列的值需要根據內容不同進行轉換顯示的需求。嘗試了一下,大概有三種方式可以實現: 1、傳統的Binding方法,後臺構造好數據,綁定就行。 2、轉換器方法(Converter),綁定後,觸發轉換器,轉換器負責把值轉換成需要的內容。 3、DataTrigger方法,直接在 ...
  • 通過前面三篇文章的介紹,我們學習瞭如何創建實體,如何創建資料庫操作,如何創建應用服務。在上一文章中我們在應用層實現了對資料庫的CURD操作。在本篇文章中,主要是使用常規的MVC方式來實現增刪改查的功能,通過完善Controller、View、ViewModel,以及調試修改控制器來實現展示層的增刪改... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...