1. 程式人生 > >.Net Core 3.0 IdentityServer4 快速入門

.Net Core 3.0 IdentityServer4 快速入門

.Net Core 3.0 IdentityServer4 快速入門

一、簡介

  IdentityServer4是用於ASP.NET Core的OpenID Connect和OAuth 2.0框架。

  將IdentityServer4部署到您的應用中具備如下特點:

  1)、認證服務

  2)、單點登陸

  3)、API訪問控制

  4)、聯合閘道器

  5)、專注於定製

  6)、成熟的開源系統

  7)、免費和商業支援

二、整體部署

 

  目前大多數的應用程式或多或少看起來是上圖所示這樣的,最常見的互動場景有(瀏覽器與Web應用程式、Web應用程式與WebApi通訊、本地應用程式獄WebApi通訊、基於瀏覽器的應用程式與WebApi 通訊、基本伺服器的應用程式與WebApi通訊、WebApi與WebApi通訊)

  前端、中間層、後端各個層級為了保護資源經常要針對相同的使用者倉儲區實現身份認證和授權,但是如果我們把這些基本的安全功能統一頒發給一個安全令牌服務,就可以不必再讓這些應用和端點之間重複實現這些基礎安全功能,重組應用程式以支援安全令牌服務將會引匯出以下體系結構和協議

 

  這樣的設計將會把安全問題分為兩個部分:(身份驗證和API訪問)

三、IdentityServer4如何提供幫助

  IdentityServer是將規範相容的OpenID Connect和OAuth 2.0端點新增到任意ASP.NET Core應用程式的中介軟體。通常,您構建(或重新使用)包含登入和登出頁面的應用程式,IdentityServer中介軟體會向其新增必要的協議頭,以便客戶端應用程式可以與其對話 使用這些標準協議。

 

四、術語

 

     1)、Users(使用者):使用者是使用已註冊的客戶端訪問資源的人

     2)、Clients(客戶端):客戶端就是從identityserver請求令牌的軟體(你可以理解為一個app即可),既可以通過身份認證令牌來驗證識別使用者身份,又可以通過授權令牌來訪問服務端的資源。但是客戶端首先必須在申請令牌前已經在identityserver服務中註冊過。實際客戶端不僅可以是Web應用程式,app或桌面應用程式(你就理解為pc端的軟體即可),SPA,伺服器程序等

  3)、Resources(資源):

  資源就是你想用identityserver保護的東東,可以是使用者的身份資料或者api資源。
  每一個資源都有一個唯一的名稱,客戶端使用這個唯一的名稱來確定想訪問哪一個資源(在訪問之前,實際identityserver服務端已經配置好了哪個客戶端可以訪問哪個資源,所以你不必理解為客戶端只要指定名稱他們就可以隨便訪問任何一個資源)。

  使用者的身份資訊實際由一組claim組成,例如姓名或者郵件都會包含在身份資訊中(將來通過identityserver校驗後都會返回給被呼叫的客戶端)。

  API資源就是客戶端想要呼叫的功能(通常以json或xml的格式返回給客戶端,例如webapi,wcf,webservice),通常通過webapi來建立模型,但是不一定是webapi,我剛才已經強調可以使其他型別的格式,這個要看具體的使用場景了。

  4)、Identity Token(身份令牌):

  一個身份令牌指的就是對認證過程的描述。它至少要標識某個使用者(Called the sub aka subject claim)的主身份資訊,和該使用者的認證時間和認證方式。但是身份令牌可以包含額外的身份資料,具體開發者可以自行設定,但是一般情況為了確保資料傳輸的效率,開發者一般不做過多額外的設定,大家也可以根據使用場景自行決定。

  5)、Access Token(訪問令牌):

   訪問令牌允許客戶端訪問某個 API 資源。客戶端請求到訪問令牌,然後使用這個令牌來訪問 API資源。訪問令牌包含了客戶端和使用者(如果有的話,這取決於業務是否需要,但通常不必要)的相關資訊,API通過這些令牌資訊來授予客戶端的資料訪問許可權。

五、程式碼快速入門 (使用客戶端憑據保護)

  1)、IdentityServer

     a)、定義Api資源和客戶端

      Api 是您系統中要保護的資源,資源的定義可以通過多種方式

      客戶端程式碼中的ClientId和ClientSecret你可以視為應用程式本身的登入名和密碼,它將您的應用程式標識到IdentityServer 伺服器,以便它知道哪個應用程式正在嘗試與其連線

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"}
                }
            };
    }
}
View Code

    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!");
            //    });
            //});
        }
    }
}
View Code

    c)、測試(如果配置合適,在瀏覽器訪問 http://localhost:5000/.well-known/openid-configuration  出現如下表示配置OK)

  首次啟動時,IdentityServer將為您建立一個開發人員簽名金鑰,該檔名為tempkey.rsa。您無需將該檔案簽入原始碼管理中,如果不存在該檔案將被重新建立。

    d)、所需的包

  2)、新增Api資源

  a)、新增一個名為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 });
        }
    }
}
View Code

  b)、配置(將身份認證服務新增到DI,並將身份驗證中介軟體新增到管道)    

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();//認證
            app.UseAuthorization();//授權


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
View Code

   AddAuthentication:將身份認證服務新增到DI比配置Bearer為預設

   AddAuthentication:將身份認證服務新增到管道中,以便對主機的每次呼叫都將自動執行身份驗證

   AddAuthentication:新增授權中介軟體,以確保匿名客戶端無法訪問我們的API資源

   http://localhost:5001/identity 在瀏覽器上訪問應返回401狀態程式碼。這意味著您的API需要憑據,並且現在受IdentityServer保護。

  c)、所需的包

 3)、建立客戶端(已控制檯的形式)

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();
        }
    }
}
View Code

  a)、所需的包

  

 4)、使用客戶端訪問Api資源

  

 

六、參考文獻

  http://docs.identityserver.io/en/latest/index.html

 如果對您有幫助,請點個推薦(讓更多需要的人看到哦)