用例子看ASP.NET Core Identity是什麼?

来源:https://www.cnblogs.com/duanyong/archive/2019/03/12/10520057.html
-Advertisement-
Play Games

@[toc] 前言 有三個重要的類Claim, ClaimsIdentity, ClaimsPrincipal,我們以一個持有合法證件的學生Bob做比方,ClaimsPrincipal就是持有證件的學生Bob,ClaimsIdentity就是學生Bob的證件駕照,Claim就是Bob駕照中的各種信息 ...


目錄

@

前言

有三個重要的類Claim, ClaimsIdentity, ClaimsPrincipal,我們以一個持有合法證件的學生Bob做比方,ClaimsPrincipal就是持有證件的學生Bob,ClaimsIdentity就是學生Bob的證件駕照,Claim就是Bob駕照中的各種信息。
下邊就開始圍繞上邊這段話展開描述:

基於聲明的認證(Claims-based Authentication)

在開始學習標識管理系統(Identity system)之前,很有必要搞清楚什麼是基於聲明的身份認證。
我們假設一個場景。Bob是一名大學生,準備去銀行為自己開戶。銀行工作人員需要Bob提供他的有效證件,於是Bob就把自己的駕照提供給了銀行工作人員。銀行工作人員可以從駕照上獲取到Bob的個人信息,例如姓名、出生日期和地址等。
Bob希望能夠享受到銀行針對大學生的優惠政策,於是銀行工作人員又請Bob提供了學生證,同時從上邊可以獲取到姓名、所在的大學名稱、院系以及學號等信息。(這裡提供別人的學生證一定是不行的!)
使用以上生活中典型的應用場景,可以幫助我們進一步去理解基於聲明(Claims-based Authentication)的身份認證。這個例子中Bob擁有兩個標識(Identity,就相當於有效的身份證明,即證明你是你的那張紙,也就是Identity):駕照+學生證。(當然還可以提供更多的Identity,比如護照、戶口本等等。)
好吧,我自己用文字越寫越怕不明白,通過上邊的這些文字,只需要清楚這麼幾點內容:

Claim

  • 就是一個鍵值對,例如:name:Bob
  • Claim可以是姓名、出身日期、地址、所在大學、學號等等信息

    Identity

  • 很多條Claim組成了一個Identity
  • Identity就是一個有效的身份證明 = 證明你是你的那張紙 = 駕照、學生證等等
  • 一個人可以擁有很多個Identity

在這裡插入圖片描述
Bob去開戶,先提供了一個Identity(這裡就是駕照),接著又提供了一個Identity(學生證)

清楚了這些,我們繼續看

在ASP.NET Core Identity中是如何實現的

ASP.NET Core 是開源的,這能夠讓我們非常方便的去學習和理解它是如何構成並運行的。源碼可以去github上查看
可以把源碼下載下來,然後查看源碼,路徑為:
corefx-master(解壓後主文件夾)/src/System.Security.Claims/src/System/Security
在這裡插入圖片描述

類ClaimsPrincipal

一個用戶(User)被聲明成ClaimsPrincipal類型(繼承自IPrincipal介面)。ClaimsPrincipal類來自System.Security.Claims命名空間。

public class ClaimsPrincipal : IPrincipal
{
    ...........
    ...........
    public virtual IIdentity Identity { get; }
    public virtual IEnumerable<ClaimsIdentity> Identities { get; }
    public virtual IEnumerable<Claim> Claims { get; }
    ...........
    ...........
    public virtual bool HasClaim(Predicate<Claim> match);
    public virtual bool HasClaim(string type, string value);
    public virtual bool IsInRole(string role);
    ...........
    ...........
}

從ClaimsPrincipal類中可以看到有一個返回類型為ClaimsIdentity集合的Identities屬性,代表著一個User可以擁有多個Identity。
在這裡的另外一個屬性Identity,不要被迷惑,他返回的是ClaimsPrincipal中主要的(如果有多個)那一個ClaimIdentity。
另外一個重要的屬性Claims,它返回了一個在ClaimsPrincipal中所有的ClaimsIdentity所包含得全部Claims的集合。

考察另外一個重要的類ClaimsIdentity

public class ClaimsIdentity : IIdentity
{
...........
...........
public virtual string AuthenticationType { get; }
public virtual string Name { get; }
public virtual bool IsAuthenticated { get; }
public virtual IEnumerable Claims { get; }
public virtual IEnumerable FindAll(Predicate match);
public virtual Claim FindFirst(string type);
public virtual bool HasClaim(string type, string value);
...........
...........
}

  • 這裡的AuthenticationType屬性從字面意思就能很好的理解,返回認證的類型,在本示例中就可能是駕照或者學生證。在ASP.NET Core 中也可能是例如:微信、QQ、Cookies、Basic、Windows、Google等等。用AuthenticationType來驗證和確定與身份相關聯的聲明用的什麼方法。
  • 還有一個IsAuthenticated屬性,用來獲取Identity是否被驗證,大家可能會感覺多餘,在沒有通過驗證的時候又怎麼會得到一個擁有Claims的Identity呢?有一個典型應用場景就是,允許游客訪問你的網站,允許使用購物車。這個游客一樣擁有由聲明(Claims)組成的標識(Identity),只是這位游客還沒有被驗證。這一非常重要的區別需要牢記。
    在ASP.NET Core 創建一個ClaimsIdentity的時候,IsAuthenticationType總會被初始化為true。一個通過驗證的用戶一定會是true,相反未被驗證的游客,此屬性為false。
  • Claims是組成Identity的全部Claim集合。

現在我們把這個假設的應用場景用圖示再總結一下:
在這裡插入圖片描述

在ASP.NET Core Identity中一同運行

上述內容在ASP.NET Core Identity 中使用Identity對象的簡單交互已經創建了一些API,例如SignInManager, UserManager ,RoleManager等,在ASP.NET Core 項目中通過依賴註入就可以使用它們。
例如,登錄管理就通過下邊一個public方法來完成登錄:

public virtual async Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, 
string authenticationMethod = null)
{
    var userPrincipal = await CreateUserPrincipalAsync(user);
    if (authenticationMethod != null)
    {
        userPrincipal.Identities.First().AddClaim(new Claim
               (ClaimTypes.AuthenticationMethod, authenticationMethod));
    }
    await Context.SignInAsync(IdentityConstants.ApplicationScheme,
        userPrincipal,
        authenticationProperties ?? new AuthenticationProperties());
}

總結

  • Claim就是一個鍵值對,用來描述一個特新,比如姓名:Bob就是一個Claim,生日:2009.9.15這也是一個Claim。其中姓名或生日就是這個Claim的一種類型,即Claimtype。
  • 一組claim就構成了一個identity,具有這些claims的identity就是 ClaimsIdentity ,也可以把ClaimsIdentity理解為“證件”,駕照就是一種ClaimsIdentity,學生證也是一種ClaimIdentity。
  • ClaimsIdentity的持有者就是ClaimsPrincipal ,一個ClaimsPrincipal可以持有多個ClaimsIdentity,就比如Bob既持有駕照(ClaimIdentity),又持有身份證(ClaimIdentity)。
    理解了Claim, ClaimsIdentity, ClaimsPrincipal這三個概念,就能理解生成登錄Cookie為什麼要用下麵的代碼?
...
var claimsIdentity = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, loginName) }, "Basic");
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
await context.Authentication.SignInAsync(_cookieAuthOptions.AuthenticationScheme, claimsPrincipal);
...

要用Cookie代表一個通過驗證的主體,必須包含Claim, ClaimsIdentity, ClaimsPrincipal這三個信息,以一個持有合法駕照的人做比方,ClaimsPrincipal就是持有證件的人Bob,ClaimsIdentity就是證件駕照,"Basic"就是證件類型(這裡假設是駕照),Claim就是駕照中的信息。
如果感覺困擾,可以再看下dudu博客的這篇文章
這篇教程中,因為自己在理解的時候花了不少時間,請大家指證!


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

-Advertisement-
Play Games
更多相關文章
  • ...
  • 回家團圓,春晚、鞭炮、春聯等都是春節的傳統代名詞,但是近兩年春節又有了一個新的代名詞,那就是“搶紅包”。今年春節期間,除了之前微信、支付寶、QQ等發紅包平臺,百度,頭條也紛紛推出了各種搶紅包活動。為了除夕夜不錯過幾個億的紅包,特意下載了一個紅包助手,用來提醒自己微信好友發紅包的信息,就這樣還是敗在了 ...
  • webservice協議 客戶端: 客戶端生成使用soapUI生成 外部提供webservice地址,地址後加?wsdl。選擇好目錄然後生成,放到項目中實現 服務端: web.xml平級目錄下創建server-config.wsdd 增加配置 <service name="目錄" provider= ...
  • 歷屆試題 列印十字圖 時間限制:1.0s 記憶體限制:256.0MB 時間限制:1.0s 記憶體限制:256.0MB 問題描述 小明為某機構設計了一個十字型的徽標(並非紅十字會啊),如下所示: ..$$$$$$$$$$$$$....$...........$..$$$.$$$$$$$$$.$$$$... ...
  • 歷屆試題 帶分數 時間限制:1.0s 記憶體限制:256.0MB 時間限制:1.0s 記憶體限制:256.0MB 問題描述 100 可以表示為帶分數的形式:100 = 3 + 69258 / 714。 還可以表示為:100 = 82 + 3546 / 197。 註意特征:帶分數中,數字1~9分別出現且只 ...
  • filter() 過濾1.結構 filter(func, iterable) ---- func函數的返回值為True,迭代iterable每個元素執行func,True則保留;False則捨去 ---- func可以使內置函數,也可以是用戶聲明的函數2.返回值 ---- fi... ...
  • 最近需要完成一個javaweb項目,但是沒有和資料庫連接而是通過websocket通訊實現和伺服器端數據交互。我搜了好多,網上大部分都是通過頁面websocket連接本地伺服器或連接異地伺服器,但是這些都把連接地址暴露在了外面,不是我想要的。本人希望websocket連接、數據處理等都是在java後 ...
  • 前言 很多人覺得Xamarin的開源少,沒法用來開發項目。 但,實際上Xamarin已經有很多開源代碼了;只要不是特別特殊的項目,基本上是都可以滿足開發。 下麵我們來看一下Xamarin中利用開源代碼ZXing.Net.Mobile進行掃碼。 引用ZXing.Net.Mobile 在Xamarin中 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...