.Net Core 3.0 IdentityServer4 快速入门
一、簡(jiǎn)介
IdentityServer4是用于ASP.NET Core的OpenID Connect和OAuth 2.0框架。
將IdentityServer4部署到您的應(yīng)用中具備如下特點(diǎn):
1)、認(rèn)證服務(wù)
2)、單點(diǎn)登陸
3)、API訪問(wèn)控制
4)、聯(lián)合網(wǎng)關(guān)
5)、專(zhuān)注于定制
6)、成熟的開(kāi)源系統(tǒng)
7)、免費(fèi)和商業(yè)支持
二、整體部署
?
目前大多數(shù)的應(yīng)用程序或多或少看起來(lái)是上圖所示這樣的,最常見(jiàn)的交互場(chǎng)景有(瀏覽器與Web應(yīng)用程序、Web應(yīng)用程序與WebApi通訊、本地應(yīng)用程序獄WebApi通訊、基于瀏覽器的應(yīng)用程序與WebApi 通訊、基本服務(wù)器的應(yīng)用程序與WebApi通訊、WebApi與WebApi通訊)
前端、中間層、后端各個(gè)層級(jí)為了保護(hù)資源經(jīng)常要針對(duì)相同的用戶(hù)倉(cāng)儲(chǔ)區(qū)實(shí)現(xiàn)身份認(rèn)證和授權(quán),但是如果我們把這些基本的安全功能統(tǒng)一頒發(fā)給一個(gè)安全令牌服務(wù),就可以不必再讓這些應(yīng)用和端點(diǎn)之間重復(fù)實(shí)現(xiàn)這些基礎(chǔ)安全功能,重組應(yīng)用程序以支持安全令牌服務(wù)將會(huì)引導(dǎo)出以下體系結(jié)構(gòu)和協(xié)議
?
這樣的設(shè)計(jì)將會(huì)把安全問(wèn)題分為兩個(gè)部分:(身份驗(yàn)證和API訪問(wèn))
三、IdentityServer4如何提供幫助
IdentityServer是將規(guī)范兼容的OpenID Connect和OAuth 2.0端點(diǎn)添加到任意ASP.NET Core應(yīng)用程序的中間件。通常,您構(gòu)建(或重新使用)包含登錄和注銷(xiāo)頁(yè)面的應(yīng)用程序,IdentityServer中間件會(huì)向其添加必要的協(xié)議頭,以便客戶(hù)端應(yīng)用程序可以與其對(duì)話 使用這些標(biāo)準(zhǔn)協(xié)議。
?
四、術(shù)語(yǔ)
? ? ?1)、Users(用戶(hù)):用戶(hù)是使用已注冊(cè)的客戶(hù)端訪問(wèn)資源的人
? ? 2)、Clients(客戶(hù)端):客戶(hù)端就是從identityserver請(qǐng)求令牌的軟件(你可以理解為一個(gè)app即可),既可以通過(guò)身份認(rèn)證令牌來(lái)驗(yàn)證識(shí)別用戶(hù)身份,又可以通過(guò)授權(quán)令牌來(lái)訪問(wèn)服務(wù)端的資源。但是客戶(hù)端首先必須在申請(qǐng)令牌前已經(jīng)在identityserver服務(wù)中注冊(cè)過(guò)。實(shí)際客戶(hù)端不僅可以是Web應(yīng)用程序,app或桌面應(yīng)用程序(你就理解為pc端的軟件即可),SPA,服務(wù)器進(jìn)程等
3)、Resources(資源):
資源就是你想用identityserver保護(hù)的東東,可以是用戶(hù)的身份數(shù)據(jù)或者api資源。
用戶(hù)的身份信息實(shí)際由一組claim組成,例如姓名或者郵件都會(huì)包含在身份信息中(將來(lái)通過(guò)identityserver校驗(yàn)后都會(huì)返回給被調(diào)用的客戶(hù)端)。
API資源就是客戶(hù)端想要調(diào)用的功能(通常以json或xml的格式返回給客戶(hù)端,例如webapi,wcf,webservice),通常通過(guò)webapi來(lái)建立模型,但是不一定是webapi,我剛才已經(jīng)強(qiáng)調(diào)可以使其他類(lèi)型的格式,這個(gè)要看具體的使用場(chǎng)景了。
4)、Identity Token(身份令牌):
一個(gè)身份令牌指的就是對(duì)認(rèn)證過(guò)程的描述。它至少要標(biāo)識(shí)某個(gè)用戶(hù)(Called the sub aka subject claim)的主身份信息,和該用戶(hù)的認(rèn)證時(shí)間和認(rèn)證方式。但是身份令牌可以包含額外的身份數(shù)據(jù),具體開(kāi)發(fā)者可以自行設(shè)定,但是一般情況為了確保數(shù)據(jù)傳輸?shù)男?#xff0c;開(kāi)發(fā)者一般不做過(guò)多額外的設(shè)置,大家也可以根據(jù)使用場(chǎng)景自行決定。
5)、Access Token(訪問(wèn)令牌):
? 訪問(wèn)令牌允許客戶(hù)端訪問(wèn)某個(gè) API 資源。客戶(hù)端請(qǐng)求到訪問(wèn)令牌,然后使用這個(gè)令牌來(lái)訪問(wèn) API資源。訪問(wèn)令牌包含了客戶(hù)端和用戶(hù)(如果有的話,這取決于業(yè)務(wù)是否需要,但通常不必要)的相關(guān)信息,API通過(guò)這些令牌信息來(lái)授予客戶(hù)端的數(shù)據(jù)訪問(wèn)權(quán)限。
五、代碼快速入門(mén) (使用客戶(hù)端憑據(jù)保護(hù))
1)、IdentityServer
? a)、定義Api資源和客戶(hù)端
Api 是您系統(tǒng)中要保護(hù)的資源,資源的定義可以通過(guò)多種方式
客戶(hù)端代碼中的ClientId和ClientSecret你可以視為應(yīng)用程序本身的登錄名和密碼,它將您的應(yīng)用程序標(biāo)識(shí)到IdentityServer 服務(wù)器,以便它知道哪個(gè)應(yīng)用程序正在嘗試與其連接
using IdentityServer4.Models; using System.Collections.Generic; namespace IdentityServer { public static class Config { public static IEnumerable<ApiResource> Apis => new List<ApiResource> { new ApiResource("api1","My API") }; public static IEnumerable<Client> Clients => new List<Client> { new Client { ClientId="client", AllowedGrantTypes =GrantTypes.ClientCredentials, ClientSecrets={ new Secret("aju".Sha256()) }, AllowedScopes={ "api1"} } }; } }????????b)、配置IdentityServer
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace IdentityServer { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { var builder = services.AddIdentityServer() .AddInMemoryApiResources(Config.Apis) .AddInMemoryClients(Config.Clients); builder.AddDeveloperSigningCredential(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIdentityServer(); //app.UseRouting(); //app.UseEndpoints(endpoints => //{ // endpoints.MapGet("/", async context => // { // await context.Response.WriteAsync("Hello World!"); // }); //}); } } }????????c)、測(cè)試(如果配置合適,在瀏覽器訪問(wèn)?http://localhost:5000/.well-known/openid-configuration? 出現(xiàn)如下表示配置OK)
首次啟動(dòng)時(shí),IdentityServer將為您創(chuàng)建一個(gè)開(kāi)發(fā)人員簽名密鑰,該文件名為tempkey.rsa。您無(wú)需將該文件簽入源代碼管理中,如果不存在該文件將被重新創(chuàng)建。
d)、所需的包
2)、添加Api資源
????a)、添加一個(gè)名為IdentityController的控制器
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Linq; namespace Api.Controllers { [Route("identity")] [Authorize] public class IdentityController : ControllerBase { public IActionResult Get() { return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); } } }????????b)、配置(將身份認(rèn)證服務(wù)添加到DI,并將身份驗(yàn)證中間件添加到管道)
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Api { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options => { options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.Audience = "api1"; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication();//認(rèn)證 app.UseAuthorization();//授權(quán) app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }??????? AddAuthentication:將身份認(rèn)證服務(wù)添加到DI比配置Bearer為默認(rèn)
AddAuthentication:將身份認(rèn)證服務(wù)添加到管道中,以便對(duì)主機(jī)的每次調(diào)用都將自動(dòng)執(zhí)行身份驗(yàn)證
AddAuthentication:添加授權(quán)中間件,以確保匿名客戶(hù)端無(wú)法訪問(wèn)我們的API資源
http://localhost:5001/identity?在瀏覽器上訪問(wèn)應(yīng)返回401狀態(tài)代碼。這意味著您的API需要憑據(jù),并且現(xiàn)在受IdentityServer保護(hù)。
????????c)、所需的包
3)、創(chuàng)建客戶(hù)端(已控制臺(tái)的形式)
using IdentityModel.Client; using Newtonsoft.Json.Linq; using System; using System.Net.Http; using System.Threading.Tasks; namespace Client { class Program { static async Task Main(string[] args) { // Console.WriteLine("Hello World!"); var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); if (disco.IsError) { Console.WriteLine(disco.Error); return; } var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest { Address = disco.TokenEndpoint, ClientId = "client", ClientSecret = "aju", Scope = "api1" }); if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json); Console.WriteLine("\n\n"); //call api var apiClient = new HttpClient(); apiClient.SetBearerToken(tokenResponse.AccessToken); var response = await apiClient.GetAsync("http://localhost:5001/identity"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(JArray.Parse(content)); } Console.ReadLine(); } } }????????a)、所需的包
4)、使用客戶(hù)端訪問(wèn)Api資源
六、參考文獻(xiàn)
http://docs.identityserver.io/en/latest/index.html
掃碼關(guān)注!您將得到及時(shí)的文章推送信息
總結(jié)
以上是生活随笔為你收集整理的.Net Core 3.0 IdentityServer4 快速入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: .NET Core ORM 类库Peta
- 下一篇: .NET Core3.0创建Worker