閱讀目錄:git
一. 什麼是Claims以及基於Claims的identity驗證github
二. 使用基於Claims的Identity驗證的優點
三. Claims是如何應用在Asp.net中?app
四,一些更深刻的補充說明async
原本想直接就開始介紹Identity的部分,奈何本身挖坑太深,高舉高打的方法不行。只能本身默默下載了Katana的源代碼研究了好一段時間。發現要想可以理解好用好Identity, Claims是一個繞不過的內容。今天就和你們一塊兒分享一下什麼是Claims以及爲何Identity要基於Claims.html
閱讀目錄:git
一. 什麼是Claims以及基於Claims的identity驗證github
二. 使用基於Claims的Identity驗證的優點
三. Claims是如何應用在Asp.net中?app
四,一些更深刻的補充說明async
實際上,基於Claims的identity驗證早已經被應用到咱們生活中的不少方面。一個很是典型的例子就是咱們到機場登機的過程。咱們乘坐飛機,是不可以直接直接拿着機票和身份證就上飛機的,須要先到櫃檯上領登機牌. 到了指定櫃檯上,出示身份證和機票,辦理物品託運,選好座位,確認後,才能換取登機牌。這個時候你才能憑藉登機牌過安檢和上飛機。ide
登機過程當中,工做人員掃一下這個小小的登機牌,就能獲取到不少信息: 好比,你已是通過航空公司認證過的乘客,你的航班號,座位號,你的名字等。工做人員只要覈對這些信息,就會容許你上對應的飛機和指定的座位。post
以Claims的角度從新看待登機過程網站
OK. 咱們再來捋一捋這個過程,用Claims的角度來從新描述和整理一下。加密
首先Claim就是一個描述. 這個例子中, 包含在登機牌上的一個一個信息,就是一個一個Claim. 這些Claims是這樣的:spa
乘客的名字叫Justrun
乘坐的航班是MF8858
座位號是34J
............................
全部上面的Claims就組成了Identity, 也就是登機牌。這個登機牌是基於Claims的。
這個登機牌是通過航空公司的工做人員驗證後,發給個人,那麼發行者航空公司就是Issuer。
登機的時候,工做人員看到你的登機牌就會放行的緣由是, 他信任這些Claims, 由於這些Claims的Issuer是trust的(航空公司)。比對完這些Claims,若是你登機的航班正確,就會讓你登機。
看起來上面的過程好像很是麻煩,不是嗎? 爲何不就拿着身份證和機票直接登機,不是更加方便乘客嗎?
它的好處就是簡單的隔離了驗證(Authentication)和受權(authorization)兩個部分,但這也是它最大的優點。
想一想看,若是咱們沒有了登機牌會是一個什麼景象。工做人員要在飛機門口擺上設備,驗證你的機票和身份證信息,給你辦理行李託運,而後讓你選座位........ 簡直就不可想象。
有了登機牌, 驗證就由航公公司來作,航空公司負責驗證和發放登機牌,空姐就只須要查看你的登機牌,讓你登機並決定你有沒有權限座頭等艙。
有了Claims Identity, 那麼建立Claims Identity就能夠由多種多樣的驗證過程來作,好比能夠經過用戶名密碼,Active Direcity, 第三方登陸(Google, Facebook,QQ,微博等),而咱們的程序就主要根據Claims Identity來判斷用戶是否可以使用咱們的系統,以及決定用戶可使用和不能使用系統中的那些功能。
這樣,驗證就徹底和應用程序分開,開發應用程序的時候,只要咱們使用的是基於Claims的Identity驗證,就不用擔憂之後驗證方式的的擴展和修改。
在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 , 和咱們的預期同樣,直接轉到了登陸頁面。
接下來,是咱們的重頭戲,咱們將給本身僞造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頁面,看看效果。
咱們的AddClaims起到效果了,經過人爲的添加Claims信息,咱們順利的獲得了訪問ProtecedPage的權限。
ClaimIdentity至關因而登機牌,也就是咱們的系統的通行證。構建的ClaimIdentity,最後會經過加密的方式,轉換成加密字符,保存到Cookie中。Authentication中間層會經過檢查用戶Cookie中是否有ClaimIdentity,來判斷當前訪問的用戶是不是合法用戶。
在上面的例子中,Issuer就是咱們本身,在AddClaims Action中,咱們直接構造了CliamIdentity. 若是使用傳統的用戶名,密碼登錄的方式的話,當驗證經過,也是一樣構造ClaimIdentity, 只是上面的例子中,咱們跳過了這步。
在Katana中,還有FacebookAuthenticationMiddleware, GoogleAuthenticationMiddleware等實現,它們是Issuer就分別是Facebook和Google. 以FacebookAuthenticationMiddleware爲例子,當FacebookAuthenticationMiddleware檢查Cookie,發麪沒有ClaimIdentity,就會轉到Facebook,要求提供Facebook帳號信息。當用戶登陸Facebook帳號,贊成受權給咱們的站點該用戶Facebook信息。這個時候FacebookAuthenticationMiddleware根據這些信息,構造CliamIdentity。
想更多的瞭解OWIN以及Katana,能夠看看下面這些文章
瞭解更多細節,能夠直接down源碼:
Katana源碼: https://katanaproject.codeplex.com/SourceControl/latest#README
Asp.net Identity源碼: https://github.com/aspnet/Identity/tree/dev/src/Microsoft.AspNet.Identity