asp.net core 3.x 身份驗證-1涉及到的概念

来源:https://www.cnblogs.com/jionsoft/archive/2020/02/11/12289419.html
-Advertisement-
Play Games

前言 從本篇開始將圍繞asp.net core身份驗證寫個小系列,希望你看完本系列後,腦子裡對asp.net core的身份驗證原理有個大致印象。至於身份驗證是啥?與授權有啥聯繫?就不介紹了,太啰嗦。你如果不曉得,自己去搜搜吧。我的學習思路是詳細看源碼 > 總結得出一個巨集觀上的印象 + 如何使用。如 ...


前言

從本篇開始將圍繞asp.net core身份驗證寫個小系列,希望你看完本系列後,腦子裡對asp.net core的身份驗證原理有個大致印象。
至於身份驗證是啥?與授權有啥聯繫?就不介紹了,太啰嗦。你如果不曉得,自己去搜搜吧。
我的學習思路是詳細看源碼 > 總結得出一個巨集觀上的印象 + 如何使用。
如果發現有啥講錯的望指正,免得誤導觀眾

我們偶爾會思考如何設計一個牛X的軟體,其實通過對asp.net core框架本身的學習更划算,一來我們熟悉了asp.net core框架,再者我們學習了微軟碰到需求是如何設計的。

計劃:

  • 基本介紹 - 概述 + 核心類介紹
  • 基於cookie/session的身份驗證原理 - 適合瀏覽器
  • 基於Token身份驗證 - 適合移動端app
  • 集成第三方登錄原理 - 比如集成微信、支付寶登錄
  • IdentityServer - 目前不鳥解
  • asp.net core Identity - 目前不鳥解

必備知識:asp.net core、配置、選項、依賴註入、中間件等...

參考:源碼Artechmvc5基於owin的身份驗證視頻

註意:本篇只講涉及到的幾個概念

 

身份驗證方式和簡易流程

常見的身份驗證方式:

  • 基於cookie/session的身份驗證原理 - 適合瀏覽器
  • 基於Token身份驗證 - 適合移動端app
  • 集成第三方登錄原理 - 比如集成微信、支付寶登錄

為了便於理解後續的概念,下麵先以最常見的 用戶密碼+cookie的身份驗證方式說說核心流程

登錄:

  1. 用戶輸入賬號密碼提交
  2. 服務端驗證賬號密碼
  3. 若驗證成功,則創建一個包含用戶標識的票證(下麵會說)
  4. 將票證加密成字元串寫入cookie

攜帶cookie請求:

  1. 用戶發起請求
  2. 身份驗證中間件嘗試獲取並解密cookie,進而得到含用戶標識的票證(下麵會說)
  3. 將用戶標識設置到HttpContext.User屬性

註意:若身份驗證中間件即使沒有解析得到用戶標識,請求也會繼續執行,此時以匿名用戶的身份在訪問系統

 

用戶標識ClaimsPrincipal

它用來表示當前登錄的用戶,它包含用戶Id + 一些與許可權檢查相關的附件屬性(角色、所屬部門)
當請求抵達時“身份驗證中間件”將從請求中解析得到當前用戶,如果獲取成功則賦值給HttpContext.User屬性

所以對於我們來說通常有兩個場景使用它
在任意能訪問HttpContext的地方獲取當前用戶,比如在Controller中。
如果需要自定義實現身份驗證,則我們要想方設法從請求中解析得到用戶,並賦值給HttpContext.User

現在你至少對用戶標識這個概念有點理解了,如果要刨根問底兒就自行搜索關鍵字:asp.net Claims

也許你曾經做過或見過這樣的設計,定義Employee表示當前系統的用戶,當用戶登錄時會從資料庫查詢得到對應的Employee,若賬號密碼驗證通過則將其放入Session或緩存中。下次訪問時直接從Session/緩存中獲取當前用戶。個人覺得這種設計存在如下問題:

  • 浪費記憶體:我們的業務代碼訪問當前用戶最多的欄位可能只是用戶id,性別、地址、聯繫電話、學歷....這些欄位不是每個業務處理都需要的
  • 拋棄了asp.net身份驗證框架:從asp.net 2.0時代微軟就設計了IPrincipal,後續的版本直到mvc5中基於owin的身份驗證都在使用此介面,後續的許可權驗證微軟也提供了,也是基於此介面的,但我們放棄了,反而是自己有寫了一套微軟本身就實現的功能,可能多數是覺得自己寫的更簡單。但我覺得判斷哪種方式更合適是在你對兩種方式都瞭解的情況下再做出判斷。

 

用戶票證AuthenticationTicket

既然有了上面的用戶標識,何不直接在登錄時加密這個標識,解析時直接解密得到呢?因為我們還需要額外的控制,比如過期時間,這個屬性只是在身份驗證階段來判斷是否過期,在我們(如Controller.Action中)使用用戶標識的時候並不需要此欄位,類似的額外欄位根據不同的身份驗證方式可能有很多,因此定義了“用戶票證”這個概念,它包含 用戶標識 + 身份驗證過程中需要的額外屬性(如得到用戶標識的時間、過期時間等)

 

身份驗證處理器AuthenticationHandler

參考上面的用戶名密碼+cookie身份驗證流程我們發現有幾個核心的處理步驟:

  • 在登錄時驗證通過後將用戶標識加密後存儲到cookie,SignIn
  • 當用戶註銷時,需要清楚代表用戶標識的cookie,SignOut
  • 在登錄時從請求中獲取用戶標識,Authenticate
  • 在用戶未登錄訪問受保護的資源時,我們希望跳轉到到登錄頁,Challenge
    • Challenge叫做質詢/挑戰,意思是當發現沒有從當前請求中發現用戶標識是希望怎麼辦,可能是跳轉到登錄頁,也可能是直接響應401,或者跳轉到第三方(如QQ、微信)的登錄頁 
  • 因為某種原因(如許可權驗證不過),阻止方案,Forbid

身份驗證處理器就是用來定義這些步驟的
asp.net core中定義了對應的介面、和抽象類,不同的身份驗證方式有不的實現類,比如基於token的身份驗證方式在SignIn時直接加密票證然後返回這個字元串(而不是寫入cookie)
這些步驟都是圍繞身份驗證來定義的,在不同地方來調用(比如在登錄頁對於的Action、在請求抵達時、在授權中間件中)

 

身份驗證選項AuthenticationSchemeOptions

在上述身份驗證處理的多個步驟中會用到一些選項數據,比如基於cookie的身份驗證 cookeName、有效時長、再比如從請求時從cookie中解析得到用戶標識後回調選項中的某個回調函數,允許我們的代碼向調試中添加額外數據,或者乾脆替換整個標識。

所以身份驗證選項用來允許我們控制AuthenticationHandler的執行。不同的身份驗證方式有不同的選項對象,它們直接或間接實現AuthenticationSchemeOptions

 

身份驗證方案AuthenticationScheme

總結性的說:身份驗證方案 = 名稱 + 身份驗證處理器類型,暫時可以理解一種身份驗證方式 對應 一個身份驗證方案,比如:
基於用戶名密碼+cookie的身份驗證方式 對應的 身份驗證方案為:new AuthenticationScheme("UIDPWDCookie",typeof(CookieAuthenticationHandler))
基於用戶名密碼+token  的身份驗證方式 對應的 身份驗證方案為:new AuthenticationScheme("JwtBearer",typeof(JwtBearerHandler))

身份驗證方案在程式啟動階段配置,啟動後形成一個身份驗證方案列表。
程式運行階段從這個列表中取出制定方案,得到對應的處理器類型,然後創建它,最後調用這個處理器做相應處理
比如登錄操作的Action中xxx.SignIn("方案名") > 通過方案名找到方案從而得到對應的處理器類型 > 創建處理器 > 調用其SignIn方法

一種特殊的情況可能多種方案使用同一個身份驗證處理器類型,這個後續的集成第三方登錄來說

 

身份驗證方案的容器AuthenticationSchemeProvider

我們說一個系統可能同時支持多種身份驗證方案,因此我們需要一個容器,可以把它理解為Dictionary<方案名,身份驗證方案>

 

身份驗證處理器容器AuthenticationHandlerProvider

可以暫時把它理解為Dictionary<方案名, 身份驗證處理器容器>,因為這個對象是每次請求都會創建,並且它提供AuthenticationHandler時時從方案列表中去找到制定方案從而得到對應的處理器類型然後創建的。如果不理解沒關係,下一篇講流程就懂了

 

身份驗證服務AuthenticationService

身份驗證中的步驟是在多個地方被調用的,身份驗證中間件、授權中間件、登錄的Action(如:AccountController.SignIn())、註銷的Action(如:AccountController.SignOut()),身份驗證的核心方法定義在這個類中,但它本質上還是去找到對應的身份驗證處理器並調用其同名方法。其實這些方法還進一步以擴展方法的形式定義到HttpContext上了。以SignIn方法為例
HttpContext.SignIn() > AuthenticationService.SignIn() > AuthenticationHandler.SignIn() 

 

後續

這一篇只儘量簡單的說了下身份驗證涉及到的幾個核心概念,如果不明白的可以留言或等到下篇結合理解。下一篇將以用戶名密碼+cookie的身份驗證方式來詳細梳理下流程。


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

-Advertisement-
Play Games
更多相關文章
  • 本文首發於公眾號「Python知識圈」,如需轉載,請在公眾號聯繫作者授權。 前言 上一篇文章整理了的公眾號所有文章的導航鏈接,其實如果手動整理起來的話,是一件很費力的事情,因為公眾號里添加文章的時候只能一篇篇的選擇,是個單選框。 面對幾百篇的文章,這樣一個個選擇的話,是一件苦差事。 pk哥作為一個 ...
  • JavaSE學習筆記(9) 集合類和泛型 1、Collection集合 集合概述 在前面我們已經學習過並使用過集合 ,那麼集合到底是什麼呢? 集合 :集合是java中提供的一種容器,可以用來存儲多個數據。 集合和數組既然都是容器,它們有什麼區別呢? 數組的長度是固定的。集合的長度是可變的。 數組中存 ...
  • JavaSE學習筆記(8) 常用類 1、Object類 類是Java語言中的根類,即所有類的父類。它中描述的所有方法子類都可以使用。在對象實例化的時候,最終找的父類就是Object。 如果一個類沒有特別指定父類,那麼預設則繼承自Object類。例如: 根據JDK源代碼及Object類的API文檔,O ...
  • 猴博士4小時講完C語言視頻教程,一共有9節課。 目錄結構如下: 目錄:/2020030-猴博士4小時講完C語言 [1G] ┣━━1.C語言基本語句(上)(更多資源訪問:www.jimeng365.cn).mp4 [87.1M] ┣━━2.C語言基本語句(下)(更多資源訪問:www.jimeng365 ...
  • 1、下載地址 http://www.erlang.org/downloads 2、下載文件 下載 OTP 22.2 Windows 64 bit Binary File 3、配置環境變數 將下載的安裝包文件安裝完成上設置環境變數,配置環境變數如下圖,將Erlang的安裝路徑下的bin文件夾的路徑添加 ...
  • 一.匿名函數 1.定義:定義函數的時候不需要定義函數名 2.具體例子: #普通函數 def add(x,y): return x + y #匿名函數 lambda x,y: x + y 調用匿名函數: f = lambda x,y: x + y #賦值後可以調用 print(f(1,2) lambd ...
  • 最近在學習C和C++,除了在寫OS的時候用到外,寫演算法的時候也會用到,整理記錄C和C++讀取數據的各種方式。 [TOC] 文章較長,總結稍微詳細了一點。 c 輸出 printf() 在 中包含最經典的輸出函數 格式化輸出,在 中格式化輸出的格式: 1)類型 | 格式字元 | 含義 | | | | | ...
  • (使用前請將其命名為GC_servy.cpp,否則可能會出錯) #include<stdlib.h> #include<stdio.h> #include<time.h> //suiji #include<string.h> #include<windows.h> //SLEEP函數 #includ ...
一周排行
    -Advertisement-
    Play Games
  • JWT(JSON Web Token)是一種用於在網路應用之間傳遞信息的開放標準(RFC 7519)。它使用 JSON 對象在安全可靠的方式下傳遞信息,通常用於身份驗證和信息交換。 在Web API中,JWT通常用於對用戶進行身份驗證和授權。當用戶登錄成功後,伺服器會生成一個Token並返回給客戶端 ...
  • 老周在幾個世紀前曾寫過樹莓派相關的 iOT 水文,之所以沒寫 Nano Framework 相關的內容,是因為那時候這貨還不成熟,可玩性不高。不過,這貨現在已經相對完善,老周都把它用在項目上了——第一個是自製的智能插座,這個某寶上50多塊可以買到,搜“esp32 插座”就能找到。一種是 86 型盒子 ...
  • 引言 上一篇我們創建了一個Sample.Api項目和Sample.Repository,並且帶大家熟悉了一下Moq的概念,這一章我們來實戰一下在xUnit項目使用依賴註入。 Xunit.DependencyInjection Xunit.DependencyInjection 是一個用於 xUnit ...
  • 在 Avalonia 中,樣式是定義控制項外觀的一種方式,而控制項主題則是一組樣式和資源,用於定義應用程式的整體外觀和感覺。本文將深入探討這些概念,並提供示例代碼以幫助您更好地理解它們。 樣式是什麼? 樣式是一組屬性,用於定義控制項的外觀。它們可以包括背景色、邊框、字體樣式等。在 Avalonia 中,樣 ...
  • 在處理大型Excel工作簿時,有時候我們需要在工作表中凍結窗格,這樣可以在滾動查看數據的同時保持某些行或列固定不動。凍結窗格可以幫助我們更容易地導航和理解複雜的數據集。相反,當你不需要凍結窗格時,你可能需要解凍它們以獲得完整的視野。 下麵將介紹如何使用免費.NET庫通過C#實現凍結Excel視窗以鎖 ...
  • .NET 部署 IIS 的簡單步驟一: 下載 dotnet-hosting-x.y.z-win.exe ,下載地址:.NET Downloads (Linux, macOS, and Windows) (microsoft.com) .NET 部署 IIS 的簡單步驟二: 選擇對應的版本,點擊進入詳 ...
  • 拓展閱讀 資料庫設計工具-08-概覽 資料庫設計工具-08-powerdesigner 資料庫設計工具-09-mysql workbench 資料庫設計工具-10-dbdesign 資料庫設計工具-11-dbeaver 資料庫設計工具-12-pgmodeler 資料庫設計工具-13-erdplus ...
  • 初識STL STL,(Standard Template Library),即"標準模板庫",由惠普實驗室開發,STL中提供了非常多對信息學奧賽很有用的東西。 vector vetor是STL中的一個容器,可以看作一個不定長的數組,其基本形式為: vector<數據類型> 名字; 如: vector ...
  • 前言 最近自己做了個 Falsk 小項目,在部署上伺服器的時候,發現雖然不乏相關教程,但大多都是將自己項目代碼複製出來,不講核心邏輯,不太簡潔,於是將自己部署的經驗寫成內容分享出來。 uWSGI 簡介 uWSGI: 一種實現了多種協議(包括 uwsgi、http)並能提供伺服器搭建功能的 Pytho ...
  • 1 文本Embedding 將整個文本轉化為實數向量的技術。 Embedding優點是可將離散的詞語或句子轉化為連續的向量,就可用數學方法來處理詞語或句子,捕捉到文本的語義信息,文本和文本的關係信息。 ◉ 優質的Embedding通常會讓語義相似的文本在空間中彼此接近 ◉ 優質的Embedding相 ...