返回顶部

Identity Server 4客户端认证控制访问API(一)

 

一、说明

我们将定义一个api和要访问它的客户端,客户端将在identityser上请求访问令牌,并使用访问令牌调用api

二、项目结构与准备

1、创建项目QuickStartIdentityServer4的asp.net 3.1项目,端口号5001,NuGet: IdentityServer4

2、创建项目API的asp.net 3.1项目,端口号5000,NuGet: Microsoft.AspNetCore.Authentication.JwtBearer

3、创建项目Client控制台项目(sp.net 3.1),模拟客户端请求,NuGet: IdentityModel

 

 

 三、QuickStartIdentityServer4项目编码

1、在QuickStartIdentityServer4项目中添加Config.cs文件

public static class Config
    {
        // 定义api范围
        public static IEnumerable<ApiScope> ApiScopes => new []
        {
            new ApiScope
            {
                Name="sample_api", // 范围名称,自定义
                DisplayName="Sample API" // 范围显示名称,自定义
            }
        };

        // 定义客户端
        public static IEnumerable<Client> Clients => new[]
        {
            new Client
            {
                ClientId="sample_client", // 客户端id
                ClientSecrets =
                {
                    new Secret("sample_client_secret".Sha256()) // 客户端秘钥

                },
                AllowedGrantTypes=GrantTypes.ClientCredentials, //授权类型为客户端
                AllowedScopes={ "sample_api" } // 设置该客户端允许访问的api范围
            }
        };

    }

2、在QuickStartIdentityServer4项目中Startup.cs文件添加配置

public void ConfigureServices(IServiceCollection services)
        {
            var builder=services.AddIdentityServer();
            builder.AddDeveloperSigningCredential();
            builder.AddInMemoryApiScopes(Config.ApiScopes);
            builder.AddInMemoryClients(Config.Clients);
        }

3、访问http://localhost:5001/.well-known/openid-configuration

 

 

 4、访问http://localhost:5001/connect/token即可拿到令牌token

 

 该token是基于jwt,我们可以在jwt官网进行查看验证,如图

 

 

 

四、API项目编码

1、Startup.cs文件配置

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

            // 添加JWT认证方案
            services.AddAuthentication("Bearer")
                     .AddJwtBearer("Bearer", option => {
                         // OIDC服务地址
                         option.Authority = "http://localhost:5001";
                         // 不使用Https
                         option.RequireHttpsMetadata = false;
                         // 设置JWT的验证参数
                         option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                         { 
                            // 因为使用的是api范围访问,该参数需设置false
                            ValidateAudience=false
                         };

                     });
            // 添加api授权策略
            services.AddAuthorization(options => {
                // "ApiScope"为策略名称
                options.AddPolicy("ApiScope", builder =>
                {
                    builder.RequireAuthenticatedUser();
                    // 鉴定claim是否存在
                    builder.RequireClaim("scope", "sample_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();

            // 认证
            app.UseAuthentication();
            // 授权
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                
                endpoints.MapControllers();
                // 设置全局策略,应用于所有api
                //endpoints.MapControllers().RequireAuthorization("ApiScope");
            });
        }

2、添加控制器IdentityServerController并增加授权

[Route("IdentityServer")]
    [Authorize("ApiScope")]
    public class IdentityServerController : ControllerBase
    {
       
       public IActionResult Get()
        {
            return new JsonResult(from claim in User.Claims select new { claim.Type,claim.Value });
        }
    }

3、拿到token并请求api

 

 

五、Client项目模拟客户端请求

internal class Program
    {
        static async Task Main(string[] args)
        {
            var client = new HttpClient();
            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5001");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }

            var tokenResponse = await client.RequestClientCredentialsTokenAsync(
                    new ClientCredentialsTokenRequest
                    { 
                        Address= disco.TokenEndpoint,
                        ClientId= "sample_client",
                        ClientSecret= "sample_client_secret"
                    }
                );

            if(tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }

            Console.WriteLine(tokenResponse.Json);


            var apiClient = new HttpClient();
            apiClient.SetBearerToken(tokenResponse.AccessToken);

            var response = await apiClient.PostAsync("http://localhost:5000/IdentityServer", null);
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }


            Console.ReadKey();
        }
    }

项目运行效果如图

 

 

学习链接地址:https://www.cnblogs.com/stulzq/p/7495129.html

posted @ 2022-07-10 19:02  SportSky  阅读(743)  评论(1编辑  收藏  举报
作者:SportSky 出处: http://www.cnblogs.com/sportsky/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。