內容:本文帶你們使用IdentityServer4進行對API受權保護的基本策略api
做者:zara(張子浩) 歡迎分享,但需在文章鮮明處留下原文地址。瀏覽器
本文將要講述如何使用IdentityServer4對API受權保護以及如何攜帶Token進行訪問受保護的API,經過HttpClient或Http請求中的body這些咱們均可以達到。那麼廢話很少說,開始吧~安全
首先咱們必定要知道,咱們訪問要訪問一個受安全限制的API的鎖子是在一個專門的IdentityServer4驗證服務器。因此呢,咱們須要建立一個認證服務器。首先咱們建立一個API項目。服務器
建立完成以後,咱們再建立一個Config.cs,固然這個名字你隨意,但你須要在DI注入的時候與其對應。在 GetSoluction 中定義了咱們的API,也就是受保護的鎖子,第一個參數是name,也就是Api的名稱,那麼後面是顯示的名字,也就是DisplayName。在 GetClients 當中咱們定義了受信任的客戶端,其中有客戶端的ID,受權方式,客戶端加密方式,經過 AllowedScopes 還定義了這個客戶端能夠訪問的API。app
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管道中,如今咱們看一下定義。ide
// 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)。ui
下面在API項目中添加控制器:this
[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服務了!
最後祝你們春運快樂。下一篇乾貨在等你們噢!