IdnentiyServer-使用客户端凭据访问API
情景如下:一個客戶端要訪問一個api,不需要用戶登錄,但是又不想直接暴露api給外部使用,這時可以使用identityserver添加訪問權(quán)限。
客戶端通過clientid和secrect訪問identitserver的Token Endpoint,獲取accesstoken;
接著客戶端再使用accesstoken作為頭部驗證訪問webapi。(webapi已經(jīng)添加了identityserver的相關(guān)驗證)。
?
代碼實現(xiàn):其中?"http://localhost:5000"是identityserver地址,"http://localhost:5001"是api地址
identityserver:在identityserver添加api和客戶端,如下所示:定義了一個api1資源,client客戶端。client客戶端指定為ClientCredentials(客戶端憑據(jù))模式,并允許其訪問api1。
public class Config{// scopes define the API resources in your systempublic static IEnumerable<ApiResource> GetApiResources(){return new List<ApiResource>{new ApiResource("api1", "My API")};}// clients want to access resources (aka scopes)public static IEnumerable<Client> GetClients(){// client credentials clientreturn new List<Client>{new Client{ClientId = "client",AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets = {new Secret("secret".Sha256())},AllowedScopes = { "api1" }}};}}?
在startup配置identityserver如下:
public class Startup{public void ConfigureServices(IServiceCollection services){// configure identity server with in-memory stores, keys, clients and scopes services.AddIdentityServer().AddDeveloperSigningCredential().AddInMemoryApiResources(Config.GetApiResources()).AddInMemoryClients(Config.GetClients());}public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseIdentityServer();}}?
WebApi:在api添加identityserver的驗證,代碼如下,其中定義了同樣的api名稱,"http://localhost:5000"是identityserver的地址。
public class Startup{public void ConfigureServices(IServiceCollection services){services.AddMvcCore().AddAuthorization().AddJsonFormatters();services.AddAuthentication("Bearer").AddIdentityServerAuthentication(options =>{options.Authority = "http://localhost:5000";options.RequireHttpsMetadata = false;options.ApiName = "api1";});}public void Configure(IApplicationBuilder app){app.UseAuthentication();app.UseMvc();}}?添加一個需要驗證的控制器:
[Route("[controller]")][Authorize]public class IdentityController : ControllerBase{[HttpGet]public IActionResult Get(){return new JsonResult(from c in User.Claims select new { c.Type, c.Value });}}?
客戶端:
這里使用里IdentityModel類庫
實際請求如下:
1.獲取accesstoken:http://localhost:5000/connect/token?client_id=client&client_secret=secret&grant_type=client_credentials&scope=api1
2.請求api1
http://localhost:5001/identityHeaders
Authorization:accesstoken
?
public class Program{public static void Main(string[] args) => MainAsync().GetAwaiter().GetResult();private static async Task MainAsync(){?//獲取identitserver的各個端點地址
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");if (disco.IsError){Console.WriteLine(disco.Error);return;}
//獲取具有api1訪問權(quán)限的accesstoken
var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");if (tokenResponse.IsError){Console.WriteLine(tokenResponse.Error);return;}Console.WriteLine(tokenResponse.Json);Console.WriteLine("\n\n");
//設(shè)置accesstoken為http請求頭,并訪問api1
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));}}}
?
ps:
1.這里默認(rèn)的accesstoken為jwt格式,客戶端訪問api時,api只需要在啟動的時候訪問identity獲取秘鑰即可。若為referencetoken,客戶端訪問api時,api需要授權(quán)訪問的都會再請求一次identityserver,,而且api必須設(shè)置秘鑰,client設(shè)置AccessTokenType屬性為Reference。
2.可自定義AccessTokenLifetime(token存活時間),默認(rèn)是3600秒,即一小時
轉(zhuǎn)載于:https://www.cnblogs.com/ldybyz/p/9761013.html
總結(jié)
以上是生活随笔為你收集整理的IdnentiyServer-使用客户端凭据访问API的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决Nginx: [error] ope
- 下一篇: springboot-RequestMa