[ASP.NET] ASP.NET Identity 中 ClaimsIdentity 解析

来源:http://www.cnblogs.com/KingJaja/archive/2016/03/02/5234290.html
-Advertisement-
Play Games

各位好 : ) 最近筆者在嘗試改用ASP.NET Identity做為新系統的認證方式,發現到網路上給的資訊,不是很完整,所以做為一個工程屍,為了避免大家遇到一樣的問題。特地將一些有趣的地方記錄下來 首先如果你是舊的專案,想要用ASP.NET Identity ,你必需要利用NuGet安裝以下幾個套


各位好 : ) 

最近筆者在嘗試改用ASP.NET Identity做為新系統的認證方式,發現到網路上給的資訊,不是很完整,所以做為一個工程屍,為了避免大家遇到一樣的問題。特地將一些有趣的地方記錄下來

首先如果你是舊的專案,想要用ASP.NET Identity ,你必需要利用NuGet安裝以下幾個套件

Microsoft.Owin.Host.SystemWeb

Microsoft.AspNet.Identity.Owin

接下來,我是在App_Start資料夾中加入Startup.cs檔,加入以下程式碼 (這裡是直接參考有用Identity的專案中的設定,但專案中是有將Startup.cs拆成兩個class ,這裡我僅用一個class檔)

public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
// Cookie Auth
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Home/Index")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ApplicationCookie);
}

再來微調一下專案中的Web.config檔

<system.web>
<authentication mode="None" />
  ------------------------------------------------------
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
</modules>

在實際要進行登入時,有二種寫法。二種都是可以的,但接下來我會講到幾個點要註意

//AuthenticationManager的獲取方式

HttpContext.GetOwinContext().Authentication;

//清除先前的登錄資訊

AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);

//第一種

IList<Claim> claims = new List<Claim>();

claims.Add(new Claim(ClaimTypes.NameIdentifier, Request["userName"].ToString()));

claims.Add(new Claim(ClaimTypes.Name, Request["userName"].ToString()));

claims.Add(new Claim(ClaimTypes.Role, "Users"));

ClaimsIdentity identity = new ClaimsIdentity(claims,

DefaultAuthenticationTypes.ApplicationCookie);

//第二種

ClaimsIdentity claimsIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie,ClaimTypes.NameIdentifier, ClaimTypes.Role);

claimsIdentity.AddClaim(new Claim( ClaimTypes.NameIdentifier, "MyCustomID"));

claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, "MyCustomUser"));

claimsIdentity.AddClaim(new Claim(
ClaimTypes.NameIdentifier, Request["userName"].ToString(),
"http://www.w3.org/2001/XMLSchema#string"));


claimsIdentity.AddClaim(
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
"My Identity", "http://www.w3.org/2001/XMLSchema#string"));

//這裡強烈建議用第二種的寫法, 原因是如果你的頁面有利用antiforgerytoken 來防CSRF攻擊時,第一種寫法會產生錯誤

//但如果用第二種寫法,並加上identityprovider 這一個Claim 。就能正常使用了,不過在本篇最下方也有提到,可以透過Global.asax.cs加入參數設定,如果是透過Global.asax.cs的話,則以上兩種寫法都是沒有問題的 : )

//登錄

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true },identity);

-----------------------------重點來了-------------------------------

我在找資料時發現在StackOverFlow上有的回應居然是錯的…

比如說像以下這篇

http://stackoverflow.com/questions/18801120/where-is-microsoft-aspnet-identity-owin-authenticationmanager-in-asp-net-identit

private async Task SignInAsync(ApplicationUser user, bool isPersistent) {

AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);

}

其實他提到的並沒有很完整,問題在哪裡呢?問題在於我們的Startup.cs中

app.UseCookieAuthentication(new CookieAuthenticationOptions

{

AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,

LoginPath = new PathString("/Home/Index")

});

// Use a cookie to temporarily store information about a user logging in with a third party login provider

//其實這一段內部實作來說跟上面是一樣的

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

其實ClaimsIdentity 最後是會用粗體的地方做為Cookie的名稱,而也是因為這樣,如果你在SignOut的方法裡指定的名稱跟Startup.cs中設定的不一樣。會導致你無法正常的登出先前使用者的資訊喔!(很重要)

有興趣可以參考這篇

CookieAuthenticationMiddelware 對cookie的加密方式

至於剛剛提到的Startup.cs ,嚴格來說其實app.UseExternalSignInCookie與app.UseCookieAuthentication只要選一種實作就可以了。參考一下UseExternalSignInCookie原始碼會發現其實他做的事情真的跟UseCookieAuthentication是差不多的

public static void UseExternalSignInCookie(this IAppBuilder app, string externalAuthenticationType) {

if (app == null) {

throw new ArgumentNullException("app");

}

app.SetDefaultSignInAsAuthenticationType(externalAuthenticationType);

app.UseCookieAuthentication(new CookieAuthenticationOptions {

AuthenticationType = externalAuthenticationType,

AuthenticationMode = AuthenticationMode.Passive,

CookieName = CookiePrefix + externalAuthenticationType,

ExpireTimeSpan = TimeSpan.FromMinutes(5),

});

}

出處

根據上面我們提到的CookieName設定,也可以知道我們如果是利用ClaimsIdentity要做登入時,CookieName也要跟Startup.cs設定的一樣,不然你會發現,明明程式碼都是對的,為什麼就是登入不了 (  ̄ c ̄)y▂ξ

ClaimsIdentity claimsIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie,ClaimTypes.NameIdentifier, ClaimTypes.Role);

另外,如果又不小心遇到AntiForgery錯誤的話 (這是微軟提供一種防CSRF攻擊的方法)

可以在Global.asax.cs檔中在Appliccation_Start加入這段。ClaimTypes就端看你的ClaimsIdentity有什麼樣的Types能用

AntiForgeryConfig.UniqueClaimTypeIdentifier  = ClaimTypes.NameIdentifier;

以上是簡單的ClaimsIdentity心得,我們下回見 : )

參考 : 

http://www.cnblogs.com/jesse2013/p/aspnet-identity-claims-based-authentication-and-owin.html#protectcookie

https://github.com/MohammadYounes/MVC5-MixedAuth/issues/20

http://dotnetcodr.com/2013/02/11/introduction-to-claims-based-security-in-net4-5-with-c-part-1/

http://stackoverflow.com/questions/19977833/anti-forgery-token-issue-mvc-5


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

-Advertisement-
Play Games
更多相關文章
  • 當使用ClaimsIdentity的時候,Asp.Net MVC在生成AntiForgeryToken的時候會預設使用User.Identity中兩種ClaimsType的值:NameIdentifier (http://schemas.xmlsoap.org/ws/2005/05/identity...
  • 面對對象編程七大原則: 1. OCP 全稱:“Open-Closed Principle” 開放-封閉原則 說明:對擴展開放,對修改關閉。 優點:按照OCP原則設計出來的系統,降低了程式各部分之間的耦合性,其適應性、靈活性、穩定性都比較好。當已有軟體系統需要增加新的功能時,不需要對作為系統基礎的抽象
  • C#代碼中時間轉換為2016-01-24 12:12:12需要如下操作: DateTime.Parse(sj).ToString("yyyy-MM-dd HH:m:ss") 但是Oracle中SQL語句中時間轉換為此格式需如下操作: to_date(sj,'yyyy-mm-dd hh24:mi:ss
  • 1.單一職責原則 即:每一個類都只專註於做一件事情 2.里氏替換原則 在對軟體功能沒有影響的前提下 子類可以替換父類出現的位置,我們就稱之為里氏替換原則 3.依賴倒置原則 實現儘量依賴抽象 不依賴實現 4.介面隔離原則 應當為客戶端提供儘量小的單獨介面,而不是總的大的介面 5.迪米特法則 即知識最少
  • 1 // 註意:首先要在項目中添加引用 System.Management 2 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Web; 7 using System.Ma
  • yyyy-MM-dd HH:mm:ss 正則表達式如下: ^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1
  • 回到目錄 我為什麼會來 在傳統的大型系統設計中,資料庫建模是個比開發更早的環節,先有資料庫,然後是ORM模型,最後才是開發程式,而這種模型在EF出現後發生了轉變,而且有可能將來會被code first取代,因為你的關係型資料庫沒有必要定死,你在部署網站時,沒人願意先建立一大堆SQL語句,誰都願意在I
  • 今天我們要談的原則有七大原則,即:單一職責,里氏替換,迪米特法則,依賴倒轉,介面隔離,合成/聚合原則,開放-封閉 。 1. 開閉原則(Open-Closed Principle, OCP) 定義:軟體實體應當對擴展開放,對修改關閉。這句話說得有點專業,更通俗一點講,也就是:軟體系統中包含的各種組件,
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...