1. 程式人生 > 實用技巧 >.Net Core 3.1 IdentityServer4 入門篇

.Net Core 3.1 IdentityServer4 入門篇

IdentityServer4是什麼?

    IdentityServer4 是為ASP.NET Core系列量身打造的一款基於 OpenID Connect 和 OAuth 2.0 認證框架。網上對於這個框架的介紹有很多,也很詳細,感興趣的小夥伴可以去多瞭解。
    官方文件https://identityserver4.readthedocs.io/en/latest/

    框架原始碼:https://github.com/IdentityServer/IdentityServer4    

整體部署

  

使用場景

    • 瀏覽器與 Web 應用程式通訊
    • Web 應用程式與 Web API 通訊(有時自己,有時代表使用者)
    • 基於瀏覽器的應用程式與 Web API 通訊
    • 本機應用程式與 Web API 通訊
    • 基於伺服器的應用程式與 Web API 通訊
    • Web API 與 Web API 通訊(有時自己,有時代表使用者)

基本術語

    

IdentityServer(標識伺服器)

  一個向客戶端頒發安全令牌的軟體。

標識伺服器有許多作業和功能 - 包括:

    • 保護您的資源
    • 使用本地帳戶儲存或通過外部標識提供程式對使用者進行身份驗證
    • 提供會話管理和單點登入
    • 管理和驗證客戶端
    • 向客戶端頒發標識和訪問令牌
    • 驗證令牌

Users(使用者)

使用者是使用註冊客戶端訪問資源的人們。

Client(客戶端)

客戶端用於驗證使用者(請求標識令牌)或訪問資源(請求訪問令牌)。客戶端必須首先註冊到標識伺服器,然後才能請求令牌。

通常客戶端包括 Web 應用程式、本機移動或桌面應用程式、SCA、伺服器程序等。

Resources(資源)

資源是您希望使用標識伺服器保護的東西,一般是一些資料和API。

資源的名稱具有唯一性。

示例

    本篇作為一個入門篇,我們就先從一個簡單的demo開始學習吧!

   1.建立IdentityServer站點

用VS2019建立一個IdentityServer站點,選擇ASP.NET Core Web 應用程式

,專案名稱自己定.

 然後安裝專案的Nuget包管理器,安裝包:IdentityServer4

配置 Startup的ConfigureServices方法

    public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpClient();
            services.AddIdentityServer().AddInMemoryApiScopes(new List<ApiScope>()
            {
                new ApiScope("api1","my api")
            }).AddInMemoryClients(new List<Client>() {
                new Client{
                    ClientId="my_client",
                    AllowedGrantTypes=GrantTypes.ClientCredentials,
                    ClientSecrets={
                        new Secret("aa123456bb".Sha256())
                    },
                    AllowedScopes={ "api1" }
                }
            }).
            AddDeveloperSigningCredential();
            //使用固定的證書,防止IdentityServer4伺服器重啟導致以往的token失效
            //AddDeveloperSigningCredential(true, "tempkey.jwk");
        }

配置Configure方法

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

啟動程式,在位址列輸入https://localhost:5001/.well-known/openid-configuration,如果出現以下資訊,則表示配置成功 

2.建立API伺服器(Resources)

  新增nuget包:IdentityModel
  

配置 Startup的ConfigureServices方法

    public void ConfigureServices(IServiceCollection services)
        {            
            services.AddHttpClient();
            services.AddControllers();

            services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options =>
            {
         //identityserver4伺服器地址 options.Authority = "https://localhost:5001"; options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false }; });
// adds an authorization policy to make sure the token is for scope 'api1' services.AddAuthorization(options => {
         //定義授權策略 options.AddPolicy("ApiScope", policy => { policy.RequireAuthenticatedUser();
            //這裡的scope的值需要在identityserver4伺服器上配置 policy.RequireClaim("scope", "api1"
); }); }); }

配置Configure方法

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

  建立一個api控制器,作為受保護的資源,在此控制器上配置授權策略,與ConfigureServices裡配置的要一致

    [Route("api/[controller]")]
    [ApiController]
    [Authorize("ApiScope")]
    public class HomeController : ControllerBase
    {       
        [HttpGet]
        public string Get()
        {
            return "success";
        }
    }

  現在直接訪問api資源伺服器,將返回401未授權狀態碼,表明api資源伺服器此時已經受到了保護.

    

  3.建立Client

  我這裡用的是WebApi,小夥伴們根據不同的需求可以選擇其他的客戶端.

    直接上程式碼

            var client = new HttpClient();
       //這裡的https://localhost:5001為IdentityServer4伺服器地址
var disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001"); if (disco.IsError) { return Content(disco.Error); } var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest { Address = disco.TokenEndpoint, ClientId = "my_client", //需要在IdentityServer4伺服器有定義 ClientSecret = "aa123456bb", //需要在IdentityServer4伺服器有定義 Scope = "api1" //需要在IdentityServer4伺服器有定義 }); if (tokenResponse.IsError) { return Content(tokenResponse.Error); } var apiClient = new HttpClient();        apiClient.SetBearerToken(tokenResponse.AccessToken);
       //訪問受保護的API資源伺服器
var content = await apiClient.GetStringAsync("https://localhost:15001/api/Home"); return Content(content);

  至此,一個簡單的demo算是完成了,希望能給小夥伴們帶來一些幫助!
  鑑於本人也是剛接觸這個框架不久,可能有些知識理解有誤,如有不正之處,敬請指正!