IdentityServer客戶端授權模式


前言

客戶端授權模,客戶端直接向Identity Server申請token並訪問資源。客戶端授權模式比較適用於服務之間的通信。
E5AD4EC9-2698-4173-8A6E-5BE17927F5E1 (1).png

搭建Identity服務

新建名為 IdentityServer 的WebApi空項目,設置端口為5000,作為我們的授權認證服務。
新建名為 Api 的WebApi空項目,設置端口為5001,作為我們的Api資源。
20191223091910.png

通過NuGet安裝 IdentityServer4 或者通過程序包管理執行 Install-Package IdentityServer4 安裝依賴包。

20191223091319.png

新一個 Config 文件來定義Identity資源

using System.Collections.Generic;
using IdentityServer4;
using IdentityServer4.Models;

namespace IdentityServer
{
    public static class Config
    {
        public static IEnumerable<IdentityResource> GetIdentityResourceResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(), //必須要添加,否則報無效的scope錯誤
            };
        }
        // scopes define the API resources in your system
        public static IEnumerable<ApiResource> GetApiResources()
        {
            //api資源({資源名稱}{描述})
            return new List<ApiResource>
            {
                new ApiResource("Api", "Api"),
            };
        }

        // clients want to access resources (aka scopes)
        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                new Client
                {
                    //客戶端id,必須唯一
                    ClientId = "client_a",
                    //授權方式,這里采用的是客戶端認證模式,只要ClientId,以及ClientSecrets正確即可訪問對應的AllowedScopes里面的api資源
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes =
                    {
                        "Api",
                    }
                }
            };
        }
    }
}

Startup 中配置IdentityServer

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace IdentityServer
{
    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)
        {
            //注入DI
            services.AddIdentityServer()
                 .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())//Api資源信息
                .AddInMemoryClients(Config.GetClients());//客戶端信息
        }

        // 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();
            }
            //放入HTTP管道中
            app.UseIdentityServer();
        }
    }
}

運行當前項目,並訪問 http://localhost:5000/.well-known/openid-configuration 就會看到當前IdentityServer的一些信,首次啟動會創建一個名為tempkey.rsa 的文件,里面保存的是你的簽名密鑰。

20191223093752.png

定義Api資源

通過NuGet安裝 IdentityServer4.AccessTokenValidation 或者通過程序包管理執行 IInstall-Package IdentityServer4.AccessTokenValidation 安裝依賴包。

Api 項目中新增一個ValuesController並添加一個 Print 接口 Authorize表示該接口被身份認證所保護

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Api.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        [HttpGet("Print")]
        [Authorize]
        public ActionResult Print()
        {
            return new JsonResult("hello word");
        }
    }
}

Startup 中把身份認證服務注入DI,並放入HTTP管道。

uusing 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();
            //將身份認證注入到DI
            services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    options.Audience = "Api";
                });
        }

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

            //身份認證添加到HTTP管道
            app.UseAuthentication();

            app.UseAuthorization();

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

測試效果

我們同時運行兩個項目。這時候我們直接訪問Api資源。會直接拋出401(用戶沒有權限訪問)

20191223110803.png

我們用配置的client向IdentityServer申請token來訪問Api資源

20191223111757.png

client_id - 我們配置的客戶端id
client_secret - 簽名密鑰。
grant_type - 授權模式
access_token - 訪問令牌
expires_in - 過去時間(秒)
token_type - 令牌類型
scope - 可以訪問資源名稱

使用資源訪問Api資源,在Hraders中加入 authorization 傳入剛申請的token(Bearer后面有一個空格)

20191223135158.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM