IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)
一.前言
本文已更新到 .NET Core 2.2
本文包括后續(xù)的Demo都會放在github:https://github.com/stulzq/IdentityServer4.Samples (QuickStart的幾個Demo隨著本系列的更新,目前為從官方Demo倉庫的拷貝,防止本文和Demo不匹配,因?yàn)楣俜紻emo和文檔一直在更新,本系列更新速度可能會慢一步)。
這里特別說明一下:快速入門以及Topic系列為了保持到最新,目前幾乎都是翻譯的官方文檔(以往的不適合最新版本就換掉了),需要深入一點(diǎn)的請看實(shí)戰(zhàn)系列。
二.使用客戶端認(rèn)證保護(hù)API
此示例介紹了使用IdentityServer保護(hù)API的最基本場景。
在這種情況下,我們將定義一個API和要訪問它的客戶端。 客戶端將在IdentityServer上請求訪問令牌,并使用它來訪問API。
三.準(zhǔn)備
創(chuàng)建一個名為QuickstartIdentityServer的ASP.NET Core Web 空項(xiàng)目(asp.net core 2.2),端口5000
創(chuàng)建一個名為Api的ASP.NET Core Web Api 項(xiàng)目(asp.net core 2.2),端口5001
創(chuàng)建一個名為Client的控制臺項(xiàng)目(.net core 2.2)
四.定義API、Identity資源
在QuickstartIdentityServer項(xiàng)目中添加一個Config.cs文件:
public static class Config{public static IEnumerable<IdentityResource> GetIdentityResources(){return new IdentityResource[]{new IdentityResources.OpenId()};}public static IEnumerable<ApiResource> GetApis(){return new List<ApiResource>{new ApiResource("api1", "My API")};}public static IEnumerable<Client> GetClients(){return new List<Client>{new Client{ClientId = "client",// no interactive user, use the clientid/secret for authenticationAllowedGrantTypes = GrantTypes.ClientCredentials,// secret for authenticationClientSecrets ={new Secret("secret".Sha256())},// scopes that client has access toAllowedScopes = { "api1" }}};}}五.定義客戶端
對于這種情況,客戶端將不具有交互式(人機(jī)交互)用戶,并將使用IdentityServer的客戶端模式進(jìn)行身份驗(yàn)證。 將以下代碼添加到Config.cs文件中:
public static IEnumerable<Client> GetClients() {return new List<Client>{new Client{ClientId = "client",// no interactive user, use the clientid/secret for authenticationAllowedGrantTypes = GrantTypes.ClientCredentials,// secret for authenticationClientSecrets ={new Secret("secret".Sha256())},// scopes that client has access toAllowedScopes = { "api1" }}}; }六.配置 IdentityServer
要配置IdentityServer以使用Scope和客戶端定義,您需要向ConfigureServices方法添加代碼。
Startup.cs
public void ConfigureServices(IServiceCollection services) {var builder = services.AddIdentityServer().AddDeveloperSigningCredential().AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryApiResources(Config.GetApis()).AddInMemoryClients(Config.GetClients());// rest omitted }public void Configure(IApplicationBuilder app) {if (Environment.IsDevelopment()){app.UseDeveloperExceptionPage();}// uncomment if you want to support static files//app.UseStaticFiles();app.UseIdentityServer();// uncomment, if you wan to add an MVC-based UI//app.UseMvcWithDefaultRoute(); }運(yùn)行此項(xiàng)目,打開瀏覽器訪問http://localhost:5000/.well-known/openid-configuration你將會看到IdentityServer的各種元數(shù)據(jù)信息。
首次啟動時,IdentityServer將為您創(chuàng)建一個開發(fā)人員簽名密鑰,它是一個名為tempkey.rsa的文件。 您不必將該文件檢入源代碼管理中,如果該文件不存在,將重新創(chuàng)建該文件。
七.添加API
在項(xiàng)目Api中添加一個Controller:IdentityController
[Route("identity")] [Authorize] public class IdentityController : ControllerBase {[HttpGet]public IActionResult Get(){return new JsonResult(from c in User.Claims select new { c.Type, c.Value });} }最后一步是將身份驗(yàn)證服務(wù)添加到DI和身份驗(yàn)證中間件到管道。 這些將:
- 驗(yàn)證傳入令牌以確保它來自受信任的頒發(fā)者
- 驗(yàn)證令牌是否有效用于此API(也稱為 audience)
將Startup更新為如下所示:
public class Startup {public void ConfigureServices(IServiceCollection services){services.AddMvcCore().AddAuthorization().AddJsonFormatters();services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options =>{options.Authority = "http://localhost:5000";options.RequireHttpsMetadata = false;options.Audience = "api1";});}public void Configure(IApplicationBuilder app){app.UseAuthentication();app.UseMvc();} }AddAuthentication 將身份認(rèn)證服務(wù)添加到DI,并將“Bearer”配置為默認(rèn)方案。 AddIdentityServerAuthentication 將 IdentityServer Token 認(rèn)證處理程序添加到DI中以供身份認(rèn)證服務(wù)使用。 UseAuthentication 將身份認(rèn)證中間件添加到管道中,因此將在每次調(diào)用API時自動執(zhí)行身份驗(yàn)證。
如果在瀏覽器訪問(http:// localhost:5001/identity),你會得到HTTP 401的結(jié)果。 這意味著您的API需要憑據(jù)。
就是這樣,API現(xiàn)在受 IdentityServer 保護(hù)。
八.創(chuàng)建客戶端
為 "Client" 項(xiàng)目添加 Nuget 包:IdentityModel
IdentityModel 包括用于發(fā)現(xiàn) IdentityServer 各個終結(jié)點(diǎn)(EndPoint)的客戶端庫。這樣您只需要知道 IdentityServer 的地址 - 可以從元數(shù)據(jù)中讀取實(shí)際的各個終結(jié)點(diǎn)地址:
// discover endpoints from metadata var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); if (disco.IsError) {Console.WriteLine(disco.Error);return; }DiscoveryClient 已在最新版移除
接下來,您可以使用從 IdentityServer 元數(shù)據(jù)獲取到的Token終結(jié)點(diǎn)請求令牌:
// request token var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest {Address = disco.TokenEndpoint,ClientId = "client",ClientSecret = "secret",Scope = "api1" });if (tokenResponse.IsError) {Console.WriteLine(tokenResponse.Error);return; }Console.WriteLine(tokenResponse.Json);九.調(diào)用API
要將Token發(fā)送到API,通常使用HTTP Authorization標(biāo)頭。 這是使用SetBearerToken擴(kuò)展方法完成的:
// call api var client = new HttpClient(); client.SetBearerToken(tokenResponse.AccessToken);var response = await client.GetAsync("http://localhost:5001/identity"); if (!response.IsSuccessStatusCode) {Console.WriteLine(response.StatusCode); } else {var content = await response.Content.ReadAsStringAsync();Console.WriteLine(JArray.Parse(content)); }輸出應(yīng)如下所示:
默認(rèn)情況下,Token將包含有關(guān) Scope,生命周期(nbf和exp),客戶端ID(client_id)和頒發(fā)者名稱(iss)的身份信息單元(Claim)。
十.使用Postman調(diào)試
十一.項(xiàng)目所用代碼
github地址: https://github.com/stulzq/IdentityServer4.Samples/tree/master/Quickstarts/1_ClientCredentials
轉(zhuǎn)載于:https://www.cnblogs.com/stulzq/p/7495129.html
總結(jié)
以上是生活随笔為你收集整理的IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: File类使用
- 下一篇: 从源码分析java.lang.Strin