• IdentityServer4 实践 使用客户端凭据保护API


    1-创建公共类库 IDS4.Core

    1.1-引用 IdentityServer4 

    1.2-创建 Config.cs 配置类

     1 using IdentityServer4.Models;
     2 
     3 namespace IDS4.Core.ClientCredentials
     4 {
     5     /// <summary>
     6     /// 配置文件(使用客户端凭据)
     7     /// </summary>
     8     public static class Config
     9     {
    10         private const string api_scope_one = "api1";
    11 
    12         public static IEnumerable<ApiScope> ApiScopes =>
    13                                                new List<ApiScope>
    14                                                {
    15                                                     new ApiScope(api_scope_one, "第一个API")
    16                                                };
    17 
    18         public static IEnumerable<Client> Clients =>
    19                                                 new List<Client>
    20                                                 {
    21                                                     new Client
    22                                                     {
    23                                                         //可以将 ClientId 和 ClientSecret 视为应用程序本身的登录名和密码
    24                                                         ClientId = "client",
    25 
    26                                                         // 没有交互式用户,使用 clientid/secret 进行身份验证
    27                                                         AllowedGrantTypes = GrantTypes.ClientCredentials,
    28 
    29                                                         // 用于身份验证的密钥
    30                                                         ClientSecrets =
    31                                                         {
    32                                                             new Secret("secret".Sha256())
    33                                                         },
    34 
    35                                                         // 客户端有权访问的范围
    36                                                         AllowedScopes = { api_scope_one }
    37                                                     }
    38                                                 };
    39 
    40     }
    41 }
    View Code

    2-创建身份服务器( Identity Server)IDS4.Server

    PS:使用站点空模板

    2.1-引用IDS4.Core

     

    2.2-配置ConfigService

    1 builder.Services.AddIdentityServer()
    2     // 这仅适用于没有证书可以使用的开发场景。
    3     .AddDeveloperSigningCredential()
    4     .AddInMemoryApiScopes(IDS4.Core.ClientCredentials.Config.ApiScopes)
    5     .AddInMemoryClients(IDS4.Core.ClientCredentials.Config.Clients);
    View Code

    2.3-配置ConfigApp

    1 var app = builder.Build();
    2 app.UseIdentityServer();
    View Code

    Ps:完整的Program.cs

     1 var builder = WebApplication.CreateBuilder(args);
     2 
     3 builder.Services.AddIdentityServer()
     4     // 这仅适用于没有证书可以使用的开发场景。
     5     .AddDeveloperSigningCredential()
     6     .AddInMemoryApiScopes(IDS4.Core.ClientCredentials.Config.ApiScopes)
     7     .AddInMemoryClients(IDS4.Core.ClientCredentials.Config.Clients);
     8 
     9 
    10 var app = builder.Build();
    11 app.UseIdentityServer();
    12 
    13 app.MapGet("/", () => "Hello World!");
    14 
    15 app.Run();
    View Code

    2.4-端口 5010

    http://localhost:5010

    3-创建API站点 IDS4.API

    PS:选 ASP.Net Core Web API 模板

    3.1-引用 Microsoft.AspNetCore.Authentication.JwtBearer 类库

    3.2-配置ConfigService

     1 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
     2     .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
     3     {
     4         //验证传入的令牌以确保它来自受信任的发行者
     5         options.Authority = "http://localhost:5010";
     6         // 禁用HTTPS
     7         options.RequireHttpsMetadata = false;
     8         options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
     9         {
    10             //验证令牌是否有效与此 API 一起使用(又名 audience 受众)
    11             ValidateAudience = false
    12         };
    13     });
    View Code

    3.3-配置ConfigApp

    app.UseAuthentication();

    Ps:完整的Program.cs

     1 using Microsoft.AspNetCore.Authentication.JwtBearer;
     2 
     3 var builder = WebApplication.CreateBuilder(args);
     4 
     5 // Add services to the container.
     6 
     7 builder.Services.AddControllers();
     8 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
     9     .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
    10     {
    11         //验证传入的令牌以确保它来自受信任的发行者
    12         options.Authority = "http://localhost:5010";
    13         // 禁用HTTPS
    14         options.RequireHttpsMetadata = false;
    15         options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    16         {
    17             //验证令牌是否有效与此 API 一起使用(又名 audience 受众)
    18             ValidateAudience = false
    19         };
    20     });
    21 // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    22 builder.Services.AddEndpointsApiExplorer();
    23 builder.Services.AddSwaggerGen();
    24 
    25 var app = builder.Build();
    26 
    27 // Configure the HTTP request pipeline.
    28 if (app.Environment.IsDevelopment())
    29 {
    30     app.UseSwagger();
    31     app.UseSwaggerUI();
    32 }
    33 
    34 app.UseAuthentication();
    35 app.UseAuthorization();
    36 
    37 app.MapControllers();
    38 
    39 app.Run();
    View Code

    3.4-端口 5011

    http://localhost:5011

     

    3.5-添加 IdentityController 控制器

     1 using Microsoft.AspNetCore.Authorization;
     2 using Microsoft.AspNetCore.Mvc;
     3 
     4 // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
     5 
     6 namespace IDS4.API.Controllers
     7 {
     8     [Route("api/[controller]")]
     9     [ApiController]
    10     [Authorize]
    11     public class IdentityController : ControllerBase
    12     {
    13         [HttpGet]
    14         public IActionResult Get()
    15         {
    16             return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
    17         }
    18     }
    19 }
    View Code

    4-创建客户端 IDS4.Web

     

     

    4.1-引用 IdentityModel 类库

    4.2-从元数据中发现端点

     1  var client = new HttpClient();
     2             var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
     3             {
     4                 Address = "http://localhost:5010",
     5                 Policy = new DiscoveryPolicy { RequireHttps = false } //禁用Https
     6             });
     7 if(disco==null || disco.IsError)
     8 {
     9    Console.WriteLine(disco.Error);
    10   return;
    11 }
    View Code

    就是解析 http://localhost:5010/.well-known/openid-configuration 这个地址

    4.3-请求令牌

     1 // 请求令牌
     2 var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
     3 {
     4     Address = disco.TokenEndpoint,
     5 
     6     ClientId = "client",
     7     ClientSecret = "secret",
     8     Scope = "api1"
     9 });
    10 
    11 if (tokenResponse.IsError)
    12 {
    13     Console.WriteLine(tokenResponse.Error);
    14     return;
    15 }
    16 
    17 Console.WriteLine(tokenResponse.Json);
    View Code

    4.4-调用API

     1 // 调用api
     2 var apiClient = new HttpClient();
     3 apiClient.SetBearerToken(tokenResponse.AccessToken);
     4 
     5 var response = await apiClient.GetAsync("https://localhost:6001/identity");
     6 if (!response.IsSuccessStatusCode)
     7 {
     8     Console.WriteLine(response.StatusCode);
     9 }
    10 else
    11 {
    12     var content = await response.Content.ReadAsStringAsync();
    13     Console.WriteLine(JArray.Parse(content));
    14 }
    View Code

    Ps:完整的Index.cshtml.cs 的get 方法

     1 public async Task OnGet()
     2         {
     3             var client = new HttpClient();
     4             var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
     5             {
     6                 Address = "http://localhost:5010",
     7                 Policy = new DiscoveryPolicy { RequireHttps = false } //禁用Https
     8             });
     9             if (disco != null)
    10             {
    11                 if (disco.IsError)
    12                     ViewData["data"] = disco.Error;
    13                 else
    14                 {
    15                     var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
    16                     {
    17                         Address = disco.TokenEndpoint,
    18                         ClientId = "client",
    19                         ClientSecret = "secret",
    20                         Scope = "api1"
    21                     });
    22                     if (tokenResponse != null)
    23                     {
    24                         if (tokenResponse.IsError)
    25                             ViewData["data"] = tokenResponse.Json;
    26                         else
    27                         {
    28                             var apiClient = new HttpClient();
    29                             apiClient.SetBearerToken(tokenResponse.AccessToken);
    30 
    31                             var response = await apiClient.GetAsync("http://localhost:5011/api/identity");
    32                             if (!response.IsSuccessStatusCode)
    33                             {
    34                                 Console.WriteLine(response.StatusCode);
    35                                 ViewData["data"] = response.StatusCode;
    36                             }
    37                             else
    38                             {
    39                                 var content = await response.Content.ReadAsStringAsync();
    40                                 ViewData["data"] = content;
    41                                 Console.WriteLine(JArray.Parse(content));
    42                             }
    43                         }
    44                     }
    45                     else
    46                     {
    47                         ViewData["data"] = "访问失败";
    48                     }
    49                 }
    50             }
    51             else
    52             {
    53                 ViewData["data"] = "访问失败";
    54             }
    55         }
    View Code

    4.5-Index.cshtml

    PS:鉴权时序图

     

    漫漫人生,唯有激流勇进,不畏艰险,奋力拼搏,方能中流击水,抵达光明的彼岸
  • 相关阅读:
    http 400 错误的请求怎么解决
    HTTP 404
    怎样在WIN7系统下安装IIS
    未能找到类型或命名空间名称“XXXX”(是否缺少 using 指令或程序集引用?) 转
    错误 1 未能找到元数据文件“C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files/wwwroot/7cb4fcd
    mklink命令转移win7系统盘文件夹users和programdata(附xp的方法)
    前端进阶之路:初涉Less
    原生js实现tooltip提示框的效果
    jquery+css实现邮箱自动补全
    前端面试中常见的算法问题读后整理
  • 原文地址:https://www.cnblogs.com/ganqiyin/p/15767223.html
Copyright © 2020-2023  润新知