IdentityServer4:客户端模式
目录
IdentityServer4:客户端模式
客户端模式不需要用户的参与,客户端(Client)向一个认证服务器发送 ClientID 和密码来换取AccessToken,然后使用AccessToken访问资源服务器受保护的资源(API)。
Api 资源项目
创建项目
打开 VS,创建一个“AspNet Core WebApi” 项目, 名为:Dotnet.WebApi.Ids4.CustomerApi
依赖包
添加依赖包
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.3" />
添加认证方案
修改 Program.cs 为如下代码:
using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace Dotnet.WebApi.Ids4.CustomerApi
{
public class Program
{
public static void Main(string[] args)
{
Console.Title = "CustomerAPI服务器";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
//IdentityServer4地址
options.Authority = "https://localhost:6001";
//认证的ApiResource名称
options.Audience = "CustomerAPIResource";
//使用JWT认证类型
options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.Urls.Add("https://*:6011");
app.UseHttpsRedirection();
//身份验证
app.UseAuthentication();
//授权
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}
代码解析:
(1) "at+jwt": 表示 JWT的类型(JsonWebTokenTypes)为 AccessToken。
(1)添加 JWT 认证:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
//IdentityServer4地址
options.Authority = "https://localhost:6001";
//认证的ApiResource名称
options.Audience = "CustomerAPIResource";
//使用JWT认证类型
options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
});
https://localhost:6001 是认证服务器地址。
添加 Api
新增文件:Controllers/CustomerController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Dotnet.WebApi.Ids4.CustomerApi.Controllers
{
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class CustomerController : ControllerBase
{
/// <summary>
/// 获取客户信息列表。
/// </summary>
/// <returns></returns>
[HttpGet("GetList")]
public IEnumerable<Customer> GetList()
{
return new List<Customer>
{
new Customer{ Id=1, Name="客户1", Phone="电话1"},
new Customer{ Id=2, Name="客户2", Phone="电话2"},
new Customer{ Id=3, Name="客户3", Phone="电话3"},
};
}
}
}
其中:
(1)在控制器上添加特性:[Authorize],这样只有登录用户才能访问,这样就起到保护了Api资源的目的。
Customer.cs
namespace Dotnet.WebApi.Ids4.CustomerApi
{
/// <summary>
/// 客户实体模型
/// </summary>
public class Customer
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Phone { get; set; }
}
}
认证服务器
创建项目
打开 VS,创建一个“AspNet Core 空” 项目,名为:Dotnet.WebApi.Ids4.AuthService
依赖包
添加依赖包
<PackageReference Include="IdentityServer4" Version="4.1.2" />
配置 IdentityServer4
创建文件:IdentityConfig.cs,添加如下代码:
using IdentityServer4.Models;
namespace Dotnet.WebApi.Ids4.AuthService
{
public static class IdentityConfig
{
/// <summary>
/// 配置API作用域。
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiScope> GetApiScopes()
{
return new List<ApiScope>
{
//客户相关API作用域
new ApiScope("Customer.Read","读取客户信息。"),
new ApiScope("Customer.Add","添加客户信息。"),
//共享API作用域
new ApiScope("News","新闻信息。")
};
}
/// <summary>
/// 配置ApiResource。
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApiResources()
{
//将多个具体的APIScope归为一个ApiResource。
return new List<ApiResource>()
{
new ApiResource("CustomerAPIResource", "客户资源")
{
Scopes={ "Customer.Read", "Customer.Add", "News" }
}
};
}
/// <summary>
/// 配置客户端应用。
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
//客户端ID。
ClientId = "AppCustomerReadClient",
//客户端凭据模式
AllowedGrantTypes = GrantTypes.ClientCredentials,
//认证密钥。
ClientSecrets =
{
new Secret("App00000001".Sha256())
},
//客户端有权访问的范围。
AllowedScopes={ "Customer.Read" }
}
};
}
}
}
其中,如下代码添加了 Client,并将其授权模式设置为:客户端模式, 并设置密码,和 Scope:
new Client
{
//客户端ID。
ClientId = "AppCustomerReadClient",
//客户端凭据模式
AllowedGrantTypes = GrantTypes.ClientCredentials,
//认证密钥。
ClientSecrets =
{
new Secret("App00000001".Sha256())
},
//客户端有权访问的范围。
AllowedScopes={ "Customer.Read" }
}
集成 IdentityServer4
修改 Program.cs 为如下代码:
namespace Dotnet.WebApi.Ids4.AuthService
{
public class Program
{
public static void Main(string[] args)
{
Console.Title = "认证和授权服务器";
var builder = WebApplication.CreateBuilder(args);
//注册IdentityServer4组件
builder.Services.AddIdentityServer()
.AddInMemoryApiScopes(IdentityConfig.GetApiScopes())
.AddInMemoryApiResources(IdentityConfig.GetApiResources())
.AddInMemoryClients(IdentityConfig.GetClients())
.AddDeveloperSigningCredential(); // 添加临时内存中的证书
var app = builder.Build();
//修改端口号
app.Urls.Add("https://*:6001");
//添加IDS4中间件。
//在浏览器中输入如下地址访问 IdentityServer4 的发现文档:https://localhost:6001/.well-known/openid-configuration
app.UseIdentityServer();
app.Run();
}
}
}
其中,app.Urls.Add("https://*:6001");
设置认证服务器的监听端口为:6001
客户端模式客户端
创建项目
新控制台项目,名为:Dotnet.WebApi.Ids4.Client
依赖包
添加依赖包
<PackageReference Include="IdentityServer4" Version="4.1.2" />
Program.cs
将 Program.cs 的代码修改为;
namespace Dotnet.WebApi.Ids4.Client
{
internal class Program
{
static void Main()
{
Console.Title = "客户端模式-客户端";
//获取AccessToken
var token = DataService.GetAccessToken();
Console.WriteLine(token);
//获取API数据
var data = DataService.GetAPIData(token);
Console.WriteLine(data.Result);
Console.ReadKey();
}
}
}
DataService.cs
using IdentityModel.Client;
using Newtonsoft.Json.Linq;
namespace Dotnet.WebApi.Ids4.Client
{
internal class DataService
{
private static readonly string ids4Url = "https://localhost:6001/";
/// <summary>
/// 获取AccessToken。
/// </summary>
/// <returns></returns>
public static string GetAccessToken()
{
var client = new HttpClient();
//获取IDS4发现文档
var disco = client.GetDiscoveryDocumentAsync(ids4Url).Result;
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return "IDS4服务器无法访问。";
}
//请求token
var tokenResponse = client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
//配置客户端信息
Address = disco.TokenEndpoint,//获取token的地址
ClientId = "AppCustomerReadClient",//客户端ID
ClientSecret = "App00000001",//客户端密钥
Scope = "Customer.Read"//访问的资源范围
}).Result;
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return "获取AccessToke错误。";
}
//以JSON格式返回Token
return tokenResponse.Json.TryGetValue("access_token").ToString();
}
private static readonly string dataUrl = "https://localhost:6011/api/customer/getlist";
/// <summary>
/// 获取API数据。
/// </summary>
/// <param name="accessToken"></param>
/// <returns></returns>
public static async Task<JArray?> GetAPIData(string accessToken)
{
JArray? jArray = null;
if (string.IsNullOrEmpty(accessToken)) return null;
//调用API
var client = new HttpClient();
//将AccessToken附加到HTTP请求的头部。
client.SetBearerToken(accessToken);
//调用远程的API。
var response = await client.GetAsync(dataUrl);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
jArray = JArray.Parse(content);
}
return jArray;
}
}
}
转载至:https://www.cnblogs.com/easy5weikai/p/17198549.html
IdentityServer4 IdentityServer 客户端 模式 客户identityserver4 identityserver客户端 模式 identityserver4 identityserver客户端 客户 identityserver4 identityserver密码 模式 identityserver4 identityserver模式 identityserver4 identityserver4 identityserver tokenrequestvalidator identityserver4 identityserver identityserver4 identityserver ocelot net6 identityserver4 identityserver net v4 identityserver4 identityserver证书 问题