從零搭建一個IdentityServer——項目搭建

  本篇文章是基於ASP.NET CORE 5.0以及IdentityServer4的IdentityServer搭建,爲何要從零搭建呢?IdentityServer4自己就有不少模板能夠直接生成一個能夠運行的驗證服務程序,是由於在真實開發過程當中很難直接用生成的模板來進行開發,其次是經過生成的方式開發者自己可能會對某些技術細節有所忽略。
   
  本文從如下幾個方面來完成IdentityServer項目搭建:

 建立一個空的Asp.net Core 5.0項目

  經過VS建立一個空的Asp.net core 5.0項目:
  注:此處選擇了Docker支持,須要安裝Docker Desktop,另外第一次經過Docker調試應用程序須要下載相應的Docker Image和VS的調試環境,若是鏡像文件下載慢,那麼能夠變動docker的註冊鏡像: https://blog.csdn.net/zhangqingmu/article/details/104655635/,若是VS調試環境下載慢可參考 https://blog.csdn.net/lindexi_gd/article/details/106925674手動下載。
  項目啓動後看到如下結果:

添加IdentityServer4組件

  IdentityServer4是一組中間件,它實現了OpenID Connect和Oauth2.0協議,來提供身份驗證以及受權服務,添加IdentityServer4僅須要安裝IdentityServer4組件,而後對相關服務和中間件進行配置便可:
 

  安裝完成後經過AddIdentityServer方法將相關的服務註冊到容器中,同時這裏返回一個builder用於繼續構建IdentityServer服務,如存儲、緩存、加密相關的密鑰等等;html

  

  接着將IdentityServer中間件添加到Asp.net core的http請求管道中:
  
  注:在添加中間件的時候須要注意IdentityServer中間件的放置順序,另外在調用UseIdentityServer這個方法中還自動添加了身份驗證的中間件。

 IdentityServer4數據持久化

  按理來講如今已經能夠運行項目了,可是運行的時候出現了沒法解析IClientStore類型錯誤:
  

   這個問題的緣由在於,IdentityServer4在進行受權時其實是依賴一系列數據的,這些數據包括Client、Resource、Scope等,因此爲了保證受權相關操做可以完成,須要配置相關數據的存儲服務,IdentityServer4默認提供了測試基於內存的數據存儲,但通常只是用於測試目的:git

   

   關於數據持久化,在.net技術棧中能夠想到的就是Entity Framework,同時IdentityServer4提供了名爲:IdentityServer4.EntityFramework的包,它包含了相關的實體類型(IdentityServer4.EntityFramework.Storage)以及EF的DbContext。因此引入IdentityServer4.EntityFramework包就能夠實現基於EF的數據持久化,另外也能夠本身實現。github

  

 

   上圖中能夠看到IdentityServer4關於EF的包有2個,可是實際上安裝IdentityServer4.EntityFramework就包含Storage這個包了:docker

  

   安裝完成以後,咱們能夠在IdentityServer4.EntityFramework.Storage包中找到如下兩個DbContext類型:shell

  ConfigurationDbContext :
  PersistedGrantDbContext :
   
  
  爲了EF可以正常工做須要根據數據庫類型安裝相應的EF數據庫提供器(本例使用的是Mariadb):

   而後就能夠對IdentityServer的存儲進行配置了:數據庫

  

  以上主要是對數據庫連接字符串、數據庫版本、字符集以及數據庫遷移程序集進行配置,須要注意的是在對數據庫進行遷移的時候默認使用DbContext所在的程序集,而IdentityServer4提供的DbContext位於IdentityServer4.EntityFramework.Storage包裏面,因此爲了可以確保遷移文件正常生成,因此須要將Startup所在的程序集設爲遷移程序集(注:更適合的方式是專門建立一個數據庫遷移項目來做爲遷移程序集,這樣數據庫遷移的相關內容能夠單獨維護)。緩存

  另外還須要注意的是數據庫連接字符串,在開發時可能數據庫安裝在本地可使用127.0.0.1,可是若是在dorcker中調試的話127.0.0.1沒法連接到數據庫。
  完成配置後便可將數據庫結構遷移到數據庫中,首先須要安裝EF的工具:
  工具描述,相關命令及參數可參考文檔 https://docs.microsoft.com/en-us/ef/core/cli/powershell
  
  執行命令(參數o表示遷移文件輸出路徑,由於存在多個DbContext以及須要多個數據遷移,因此分開存儲):
  Add-Migration initPersistedGrantDb -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb
  Add-Migration initConfigurationDb -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb

  注:-c和-o分別是-Context 和-OutputDir 的簡寫,在參數沒有二義性時可使用簡寫。服務器

  生成的文件:
  

  執行數據庫更新命令後,數據庫將完成建立:ide

  Update-Database -Context PersistedGrantDbContext
  Update-Database -Context ConfigurationDbContext
  

  數據庫也就建立好了:工具

  

   啓動程序,並訪問https://localhost:55006/.well-known/openid-configuration便可看到如下內容,證實IdentityServer4已經成功啓動了:

  

  可是因爲數據庫中尚未任何數據,因此還沒法進行受權操做,由於數據庫中尚未任何數據,這裏簡單的把IdentityServer4模板建立的建立初始數據代碼引入,並完成數據建立:
  

   注:關於IdentityServer4的默認數據可經過命令「dotnet new -i IdentityServer4.Templates」先安裝IdentityServer4相關模板,而後使用「dotnet new is4ef」命令來建立,具體參考文檔:https://identityserver4.readthedocs.io/en/latest/quickstarts/5_entityframework.html

  在啓動參數中包含「/seed」時建立數據,關於啓動參數,能夠直接執行程序時添加,如dotnet .\IdentityServer.dll /seed,或者經過VS中設置調試參數進行調試(數據生成後刪除):
  

配置IdentityServer4證書

  運行程序,經過測試數據中的client及其密碼嘗試獲取access token:

  

  啊哦,出錯了,未配置簽名證書,沒法建立Jwt token,簡單來講就是爲了保證token的簽名和驗證,須要配置一個數字簽名證書,關於證書配置可參考文檔: https://identityserver4.readthedocs.io/en/latest/topics/startup.html#key-material
  爲了方便,使用開發證書進行測試:
  

   添加代碼後再次運行程序,就可以生成Access Token 了:

建立一個基於Jwt身份驗證的WebApi項目

  最後經過VS新建一個默認的WebApi項目來驗證一下是否可以經過access_token訪問受保護資源。
  在新建的項目中添加基於Jwt bearer的驗證服務:
  
  同時添加身份驗證中間件:
  

   設置API的受權訪問:

  

  獲取token後訪問受保護API:
  

   成功訪問,可是這裏有個小細節須要注意一下,就是當獲取到access token後,在token的有效期內,哪怕是把IdentityServer關閉,也能使用token正常訪問受保護資源,換句話說access token頒發後就與IdentityServer無關了,以上內容其實是使用Asp.Net core 5.0以及IdentityServer4實現了一個基於客戶端證書(Client Credentials)的Oauth2.0受權流程,但IdentityServer提供的內容不只於此,後續文章將會對該IdentityServer繼續完善,使其成爲一個功能完善的身份驗證服務。

小結 

  本篇文章從一個空項目開始,不斷往裏面添加組件和代碼,搭建了一個基於IdentityServer4的身份驗證服務器,而且到目前爲止已經實現了IdentityServer4的相關數據持久化,而且可以經過Client_Credentials等方式獲取Access Token,實現了基於Jwt的身份驗證,這一切實際上都是基於Oauth2.0協議的,關於Oauth2.0能夠參考文章:https://www.cnblogs.com/selimsong/p/8037717.html
  但IdentityServer4是一個實現OpenIDConnect協議的身份驗證/受權服務,更多內容將在後續文章中介紹。
參考:
 
相關文章
相關標籤/搜索