前面的文章使用Asp.net core 5.0以及IdentityServer4搭建了一個基礎的驗證服務器,並實現了基於客戶端證書的Oauth2.0受權流程,以及經過access token訪問被保護資源,本文將繼續完善IdentityServer實現與Identity組件的集成,可以使用Identity的用戶來完成受權。html
在軟件領域中只要提到身份驗證就能想到登陸,而登陸每每與用戶名和密碼相關聯,IdentityServer4或者說OAuth2.0和OpenIDConnect也是同樣的,它須要用戶數據來支持完成相關的驗證及受權操做,下面咱們就先來實現IdentityServer4的用戶數據接入及與用戶數據相關的受權流程。數據庫
首先爲IdentityServer添加Asp.Net core Identity模塊:api
Asp.net core Identity是Asp.net core的身份驗證組件,它不只包含了身份驗證所需的數據及數據持久化支持,另外還提供了用戶管理、登陸管理等一系列的服務和UI,在建立新的Asp.net core mvc或api項目時,若是勾選身份驗證選項就會默認包含該組件,可是因爲文本中的例子是從零開始的,因此Identity組件也須要手動添加。服務器
在添加Identity以前還有一個概念須要再說一下就是metapackege(元包,具體參考:https://natemcmaster.com/blog/2018/08/29/netcore-primitives-2/),它實質上是一組共享庫,提供了.net core和asp.net core應用的基礎運行時和基礎功能,在建立項目時默認會依賴相應.net core版本的元包,而元包共享的程序集實際上在dotnet的安裝目錄的shared目錄下,元包的好處就是在框架發佈時,發佈文件就不須要包含元包內容,減小發布文件大小:mvc
而Asp.net core 5.0應用程序包含兩個元包:框架
其中Microsoft.AspNetCore.App中包含了Identity的基礎組件:asp.net
基礎組件中已經包含了Identity的基礎組件,如IdentityUser等相關的實體以及相關的服務類型/接口,因此換句話說使用Identity功能僅須要完成數據持久化及UI便可。ide
EF core是.net core下面的首選數據持久化框架,因此一樣的identity也提供了基於EF core的數據持久化組件,添加基於EF的Identity數據持久化組件:佈局
同時爲了方便後續的擴展,新建一個ApplicationUser繼承於IdentityUser和ApplicationDbContext繼承於IdentityDbContext<ApplicationUser>:visual-studio
添加Identity的數據上下文及identity服務:
添加數據庫遷移代碼並更新到數據庫:
Add-Migration initIdentityDb -c ApplicationDbContext -o Migrations/IdentityServer/IdentityDb
Update-Database -Context ApplicationDbContext
Identity的UI是一個Razor的類庫,換句話說就是頁面文件被包含在類庫裏面了,若是要對UI進行修改能夠經過VS的構建程序構建(VS Code可參考文檔:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-5.0&tabs=netcore-cli#scaffold-identity-into-an-empty-project):
在對話框中選擇「標識(Identity)」中的「標識(Identity)」選項:
在標識對話框中勾選「替代全部文件」,佈局文件沒有留空便可,最後選擇Identity的DbContext便可:
添加Razor服務、靜態文件處理中間件(訪問js等文件)及Razor終結點映射:
訪問登陸地址:https://localhost:55002/Identity/Account/Login
到目前爲止identity的數據庫和UI都已經添加到項目中而且能夠運行了,可是還存在一些問題,如默認的Identity UI相關功能依賴IEmailSender組件等等,同時還須要與IdentityServer4集成,其登陸、註冊、登出等基礎功能須要根據IdentityServer4自己的一些需求進行修改。
下面就進入IdentityServer4與Asp.net core Identity的集成工做,首先先添加IdentityServer4.AspNetIdentity組件:
而後經過IIdentityBuilder向容器中添加相關服務:
最後對修改一下Identity的註冊代碼,將與IEmailSender有關的代碼註釋掉(注:默認生成代碼中包含郵件發送邏輯,可是沒有EmailSender的實現,除了註釋相關代碼外也能夠實現一個IEmailSender並註冊到容器中來解決問題):
啓動應用,訪問註冊頁面註冊用戶:https://localhost:55002/Identity/Account/Register
註冊成功後,在數據庫中爲相應的client信息手動添加一條基於用戶名密碼的Grant Type(password),便可使用註冊的用戶來經過password的方式獲取access token了:
如下是經過剛註冊用戶名密碼得到的access token:
對上面的access token解碼後能夠看到它的payload部分包含如下信息(sub使用了用戶的Id):
小提示:在IdentityServer4中獲取Token時會根據請求對攜帶的Client信息以及相關參數進行驗證,本例中若是Client不支持Password的Grant Type,那麼會致使不支持相應的受權類型而致使沒法正確得到Access Token,遇到沒法正確得到Access Token或者一些驗證錯誤的時候能夠在調試模式下查看IdentityServer的輸出,裏面會包含相關受權成功/失敗的信息。
本篇文章經過集成asp.net core identity組件實現了用戶管理,包括註冊、登陸等,而且實現了經過註冊的用戶,基於Oauth2.0的用戶名密碼模式(password grant type)來獲取到Access Token,但就目前爲止本系統文章所實現的、演示的IdentityServer功能仍舊是基於Oauth2.0協議,從下一篇文章開始就會開始介紹OpenIDConnect(oidc)相關的內容,此外現階段實現的Identity登陸也僅僅只是Identity自己的內容,針對OpenIDConnect或者說IdentityServer4它還有一些額外的操做,如事件、受權贊成等等,這些內容也會在後續文章中不斷完善。
參考:
https://natemcmaster.com/blog/2018/08/29/netcore-primitives-2/