.NET Core IdentityServer4實戰 第一章-入門與API新增客戶端憑據
內容:本文帶大家使用IdentityServer4進行對API授權保護的基本策略
作者:zara(張子浩) 歡迎分享,但需在文章鮮明處留下原文地址。
本文將要講述如何使用IdentityServer4對API授權保護以及如何攜帶Token進行訪問受保護的API,通過HttpClient或Http請求中的body這些我們都可以達到。那麼廢話不多說,開始吧~
首先我們一定要知道,我們訪問要訪問一個受安全限制的API的鎖子是在一個專門的IdentityServer4驗證伺服器。所以呢,我們需要建立一個認證伺服器。首先我們建立一個API專案。
建立完成之後,我們再建立一個Config.cs,當然這個名字你隨意,但你需要在DI注入的時候與其對應。在 GetSoluction 中定義了我們的API,也就是受保護的鎖子,第一個引數是name,也就是Api的名稱,那麼後面是顯示的名字,也就是DisplayName。在 GetClients 當中我們定義了受信任的客戶端,其中有客戶端的ID,授權方式,客戶端加密方式,通過 AllowedScopes 還定義了這個客戶端可以訪問的API。
using IdentityServer4.Models; using System.Collections.Generic; namespace IdentityServerSolution { /// <summary> /// zaranet 2019.1.26 14.10 create this file /// Config是IdentityServer的配置檔案,一會我們需要註冊到DI層。 /// </summary> public class Config { /// <summary> /// 這個ApiResource引數就是我們Api /// </summary> /// <returns></returns> public static IEnumerable<ApiResource> GetSoluction() { return new[] { new ApiResource("api1", "MY API") }; } public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "Client", AllowedGrantTypes = GrantTypes.ClientCredentials, ClientSecrets = { new Secret("secret".Sha256()), }, AllowedScopes = {"api1"} } }; } } }
我們現在已經寫好了關於IdentityServer4伺服器的配置檔案,那麼我們還需要去依賴注入到.NET Core管道中,現在我們看一下定義。
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddIdentityServer() .AddInMemoryApiResources(Config.GetSoluction()) .AddInMemoryClients(Config.GetClients()) .AddDeveloperSigningCredential(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //新增認證中介軟體 app.UseIdentityServer(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); }
就是這樣 - 如果您執行伺服器並瀏覽瀏覽器 http: // localhost:您的埠/.well-known/openid-configuration ,您應該會看到所謂的發現文件。 客戶端和API將使用它來下載必要的配置資料。
首次啟動時,IdentityServer將為您建立一個開發人員簽名金鑰,它是一個名為的檔案 tempkey.rsa
。您不必將該檔案檢入原始碼管理中,如果該檔案不存在,將重新建立該檔案。
以下是用PostMan進行的測試,以HttpPost方式進行請求,並在Http Body中進行編輯請求體上下文,測試結果如下。如果三個引數沒有問題就返回token,如果其中三個引數有一個寫錯,那麼就會返回400錯誤(error:invalid_client)。
下面在API專案中新增控制器:
[Route("identity")] [Authorize] [ApiController] public class IdentityController : ControllerBase { [HttpGet] public IActionResult Get() { return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); } }
稍後將使用此控制器來測試授權要求,以及通過API的眼睛視覺化宣告身份。現在我們將身份驗證服務新增到DI和身份驗證中間價到管道中,驗證傳入令牌以確保它來自受信任的頒發者。
將Startup 更新 為如下所示:
public void ConfigureServices(IServiceCollection services) { services.AddMvcCore() .AddAuthorization() .AddJsonFormatters(); services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = "http://localhost:58653"; options.RequireHttpsMetadata = false; options.Audience = "api1"; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseAuthentication(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); }
AddAuthentication 是為了用於將IdentityServer4訪問令牌驗證處理程式將在DI中提供身份驗證服務。 UseAuthentication 將身份驗證中介軟體新增到管道中,以便在每次呼叫主機時自動執行身份驗證。如果你現在轉到 http://localhost:prot/identity 中是401錯誤的話,說明API已經得到了保護。配置成功了!,現在我們要建立我們的客戶端了。去訪問受保護的API需要攜帶鑰匙,那麼這個鑰匙術語叫做令牌,那就是通往大門的令牌!現在立刻建立一個控制檯程式,使用令牌訪問API。 首先我們需要安裝IdentityModel,因為它可以替我們找到元資料。
IdentityModel包括用於發現端點的客戶端庫。這樣您只需要知道IdentityServer的基地址 - 可以從元資料中讀取實際的端點地址:
var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://localhost:58653"); if (disco.IsError) { Console.WriteLine(disco.Error); return; }
接下來,您可以使用發現文件中的資訊來請求令牌:
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest { Address = disco.TokenEndpoint, ClientId = "Client",//id ClientSecret = "secret", //pwd Scope = "api1"//請求的api }); if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; }
要將訪問令牌傳送到API,通常使用HTTP Authorization標頭。 這是使用 SetBearerToken 擴充套件方法 完成的 :
var Apiclient = new HttpClient(); Apiclient.SetBearerToken(tokenResponse.AccessToken); var response = await client.GetAsync("http://localhost:58653/identity"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(JArray.Parse(content)); }
就這樣,我們啟動結果如下,啟動順序,應先啟動身份認證平臺,然後再啟動API,在啟動控制檯除錯工具。
就這樣一個簡單的IdentityServer4身份認證平臺就OK了,現在是不是想要迫切的試一下呢?哈哈,關於原始碼,我放到我的Coding中了,地址是:https://coding.net/u/zaranet/p/IdentitySERVER,當然不要看著簡單,還是自己敲一下吧,如果你一點都沒有碰過IdentityServer的話。下面我們在回顧一下。
我們在 IdentityServerSoluction 中定義了 Config 檔案,用於Id4的配置,主要功能是為了認證模型,其中還設定了Client請求文中的 ClientId 這些引數等等。那麼 IdentItyAPI 就是我們的專案服務,其中通過 Authorize 標記的都是具有安全保護的API控制器,那麼我們就需要去獲取我們的 IdentityServerSoluction 中的驗證,這樣我們才可以訪問,那麼我們就用了.NET Core控制檯程式去模擬了這個過程,其中涉及了 HttpClient 相關知識。那麼最後返回了我們的相關 token ,這樣,我們可以根據 token 去獲取我們想要的API服務了!
最後祝大家春運快樂。下一篇乾貨在等大家噢!