全新的membership框架Asp.net Identity(2)——繞不過的Claims


本來想直接就開始介紹Identity的部分,奈何自己挖坑太深,高舉高打的方法不行。只能自己默默下載了Katana的源代碼研究了好一段時間。發現要想能夠理解好用好Identity, Claims是一個繞不過的內容。今天就和大家一起分享一下什么是Claims以及為什么Identity要基於Claims.

閱讀目錄:

一. 什么是Claims以及基於Claims的identity驗證

二. 使用基於Claims的Identity驗證的優勢

三. Claims是如何應用在Asp.net中?

四,一些更深入的補充說明

一,什么是Claims以及基於Claims的identity驗證

image

實際上,基於Claims的identity驗證早已經被應用到我們生活中的很多方面。一個非常典型的例子就是我們到機場登機的過程。我們乘坐飛機,是不能夠直接直接拿着機票和身份證就上飛機的,需要先到櫃台上領登機牌. 到了指定櫃台上,出示身份證和機票,辦理物品托運,選好座位,確認后,才能換取登機牌。這個時候你才能憑借登機牌過安檢和上飛機。

登機過程中,工作人員掃一下這個小小的登機牌,就能獲取到很多信息: 比如,你已經是經過航空公司認證過的乘客,你的航班號,座位號,你的名字等。工作人員只要核對這些信息,就會允許你上對應的飛機和指定的座位。

以Claims的角度重新看待登機過程

OK. 我們再來捋一捋這個過程,用Claims的角度來重新描述和整理一下。

首先Claim就是一個描述. 這個例子中, 包含在登機牌上的一個一個信息,就是一個一個Claim. 這些Claims是這樣的:

乘客的名字叫Justrun

乘坐的航班是MF8858

座位號是34J

............................

所有上面的Claims就組成了Identity, 也就是登機牌。這個登機牌是基於Claims的。

這個登機牌是經過航空公司的工作人員驗證后,發給我的,那么發行者航空公司就是Issuer。

登機的時候,工作人員看到你的登機牌就會放行的原因是, 他信任這些Claims, 因為這些Claims的Issuer是trust的(航空公司)。比對完這些Claims,如果你登機的航班正確,就會讓你登機。

二,使用基於Claims的Identity驗證的優勢

看起來上面的過程好像非常麻煩,不是嗎? 為什么不就拿着身份證和機票直接登機,不是更加方便乘客嗎?

它的好處就是簡單的隔離了驗證(Authentication)和授權(authorization)兩個部分,但這也是它最大的優勢。

想想看,如果我們沒有了登機牌會是一個什么景象。工作人員要在飛機門口擺上設備,驗證你的機票和身份證信息,給你辦理行李托運,然后讓你選座位........ 簡直就不可想象。

有了登機牌, 驗證就由航公公司來做,航空公司負責驗證和發放登機牌,空姐就只需要查看你的登機牌,讓你登機並決定你有沒有權限座頭等艙。

有了Claims Identity, 那么創建Claims Identity就可以由多種多樣的驗證過程來做,比如可以通過用戶名密碼,Active Direcity, 第三方登錄(Google, Facebook,QQ,微博等),而我們的程序就主要根據Claims Identity來判斷用戶是否能夠使用我們的系統,以及決定用戶可以使用和不能使用系統中的那些功能。

820a5da5-9230-497c-8bd2-7a861dd227f9

這樣,驗證就完全和應用程序分開,開發應用程序的時候,只要我們使用的是基於Claims的Identity驗證,就不用擔心以后驗證方式的的擴展和修改。

三,Claims是如何應用在Asp.net中?

在Visual Studio 2013中,創建一個Asp.net MVC項目。這個默認的Asp.net MVC項目中,權限驗證默認使用的是CookieAuthentication。

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
     AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
     LoginPath = new PathString("/Account/Login"),
     Provider = new CookieAuthenticationProvider
     {
          // Enables the application to validate the security stamp when the user logs in.
          // This is a security feature which is used when you change a password or add an external login to your account.  
          OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
          validateInterval: TimeSpan.FromMinutes(30),
          regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
      }
});  

啟動網站,能夠看到常規的登錄注冊流程。當我們要訪問受保護的頁面的時候,會轉到登錄頁面上。

現在我們在這個默認的MVC項目中做個小試驗,不通過注冊,登錄,直接寫入偽造的Claims信息來通過驗證。

首先,我們在ManageController上,添加一個ProtectedPage頁面,由於ManageController整個Controller都添加上了[Authorize],所以默認ProtectedPage是需要登錄之后才能訪問的。

public async Task<ActionResult> ProtectedPage()
{
    return new ContentResult { Content = "This is a protected Page" };
}

直接敲入網址,http://localhost:4572/Manage/ProtectedPage , 和我們的預期一樣,直接轉到了登錄頁面。

436feb38-2b22-4570-82f2-b162817db0b3

接下來,是我們的重頭戲,我們將給自己偽造Claims, 騙過Authentication, 獲得訪問ProtectedPage的權限。

在HomeController上,創建一個AddClaim頁面,偽造Claims的過程如下:

public ActionResult AddClaim()
{
     var claims = new List<Claim>//創建我們的Claim
     {
           new Claim(ClaimTypes.Name, "Peter"),
           new Claim(ClaimTypes.Email, "justrun_test@outlook.com")
     };
     var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);//構建ClaimsIdentity
     var ctx = Request.GetOwinContext();
     var authenticationManager = ctx.Authentication;//通過OWIN Context獲取我們的Authentication Manager
     authenticationManager.SignIn(identity);
     return Content("Login Success");
}

  訪問AddClaims頁面,看看效果。

 9a2b8af3-a25a-4cbc-a237-8e413b0edb88

我們的AddClaims起到效果了,通過人為的添加Claims信息,我們順利的得到了訪問ProtecedPage的權限。

 四,一些更深入的補充說明

1. AuthenticationMiddleware如何判斷用戶是否是合法用戶的?

ClaimIdentity相當於是登機牌,也就是我們的系統的通行證。構建的ClaimIdentity,最后會通過加密的方式,轉換成加密字符,保存到Cookie中。Authentication中間層會通過檢查用戶Cookie中是否有ClaimIdentity,來判斷當前訪問的用戶是否是合法用戶。

2. 誰是Issuer?

在上面的例子中,Issuer就是我們自己,在AddClaims Action中,我們直接構造了CliamIdentity. 如果使用傳統的用戶名,密碼登陸的方式的話,當驗證通過,也是同樣構造ClaimIdentity, 只是上面的例子中,我們跳過了這步。

在Katana中,還有FacebookAuthenticationMiddleware, GoogleAuthenticationMiddleware等實現,它們是Issuer就分別是Facebook和Google. 以FacebookAuthenticationMiddleware為例子,當FacebookAuthenticationMiddleware檢查Cookie,發面沒有ClaimIdentity,就會轉到Facebook,要求提供Facebook賬號信息。當用戶登錄Facebook賬號,同意授權給我們的站點該用戶Facebook信息。這個時候FacebookAuthenticationMiddleware根據這些信息,構造CliamIdentity。

3. 補充閱讀:

想更多的了解OWIN以及Katana,可以看看下面這些文章

OWIN產生的背景以及簡單介紹

Katana介紹以及使用

OWIN Middleware

了解更多細節,可以直接down源碼:

Katana源碼: https://katanaproject.codeplex.com/SourceControl/latest#README

Asp.net Identity源碼: https://github.com/aspnet/Identity/tree/dev/src/Microsoft.AspNet.Identity

6e92455c-1c0c-4a06-bf4d-d19b8433ab5a

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM