從零搭建一個IdentityServer——整合Asp.net core Identity

7m魚發表於2021-01-28

  前面的文章使用Asp.net core 5.0以及IdentityServer4搭建了一個基礎的驗證伺服器,並實現了基於客戶端證照的Oauth2.0授權流程,以及通過access token訪問被保護資源,本文將繼續完善IdentityServer實現與Identity元件的整合,可使用Identity的使用者來完成授權。

整合Asp.net core Identity

  在軟體領域中只要提到身份驗證就能想到登入,而登入往往與使用者名稱和密碼相關聯,IdentityServer4或者說OAuth2.0和OpenIDConnect也是一樣的,它需要使用者資料來支援完成相關的驗證及授權操作,下面我們就先來實現IdentityServer4的使用者資料接入及與使用者資料相關的授權流程。

  首先為IdentityServer新增Asp.Net core Identity模組:

  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目錄下,元包的好處就是在框架釋出時,釋出檔案就不需要包含元包內容,減少釋出檔案大小:

   

 

   而Asp.net core 5.0應用程式包含兩個元包:

   

  其中Microsoft.AspNetCore.App中包含了Identity的基礎元件:

   

  基礎元件中已經包含了Identity的基礎元件,如IdentityUser等相關的實體以及相關的服務型別/介面,所以換句話說使用Identity功能僅需要完成資料持久化及UI即可。

   

Asp.net core Identity資料持久化

  EF core是.net core下面的首選資料持久化框架,所以同樣的identity也提供了基於EF core的資料持久化元件,新增基於EF的Identity資料持久化元件:

   

 

   同時為了方便後續的擴充套件,新建一個ApplicationUser繼承於IdentityUser和ApplicationDbContext繼承於IdentityDbContext<ApplicationUser>:

   

  新增Identity的資料上下文及identity服務:

   

  新增資料庫遷移程式碼並更新到資料庫:

  Add-Migration initIdentityDb -c ApplicationDbContext -o Migrations/IdentityServer/IdentityDb

  Update-Database -Context ApplicationDbContext

   

Asp.net core Identity UI

  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本身的一些需求進行修改。

Asp.net core Identity與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://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-5.0&tabs=visual-studio

https://natemcmaster.com/blog/2018/08/29/netcore-primitives-2/

 本文連結:https://www.cnblogs.com/selimsong/p/14338193.html

相關文章