可通过多种方式从代理调用自定义 API。 根据你的方案,可以使用IDownstreamApi、MicrosoftIdentityMessageHandler或IAuthorizationHeaderProvider中的任意一个。 本指南解释了三种不同方法来调用您自己的受保护 API。
若要从代理调用 API,需要获取代理可用于向 API 进行身份验证的访问令牌。 建议使用适用于 .NET 的 Microsoft.Identity.Web SDK 调用 Web API。 此 SDK 简化了获取和验证令牌的过程。 对于其他语言,请使用 Microsoft Entra ID 身份验证 SDK (sidecar)。
先决条件
- 具有调用目标 API 的适当权限的代理标识。 你需要一个代表流的用户。
- 具有调用目标 API 的适当权限的代理用户帐户。
根据方案确定使用哪种方法
下表可帮助你确定使用哪种方法。 对于大多数方案,我们建议使用 IDownstreamApi。
| Approach | 复杂性 | 灵活性 | 用例 |
|---|---|---|---|
IDownstreamApi |
低 | Medium | 带有配置选项的标准 REST API |
MicrosoftIdentityMessageHandler |
Medium | 高 | 具有直接注入(DI)和可组合管道的 HttpClient |
IAuthorizationHeaderProvider |
高 | 非常高 | 完全控制 HTTP 请求 |
IDownstreamApi 是三个选项中调用受保护 API 的首选方法。 它高度可配置,需要最少的代码更改。 它还提供自动令牌获取。
需要以下列出的项时使用 IDownstreamApi :
- 正在调用标准 REST API
- 需要配置驱动的方法
- 需要自动序列化/反序列化
- 你想要编写最少的代码
调用 API
确定适合自己的内容后,继续调用自定义 Web API。
Warning
由于安全风险,客户端机密不应在生产环境中用作代理标识蓝图的客户端凭据。 而是使用更安全的身份验证方法 ,例如将联合标识凭据(FIC)与托管标识 或客户端证书配合使用。 这些方法通过消除直接在应用程序配置中存储敏感机密的需要,从而提供增强的安全性。
安装所需的 NuGet 包:
dotnet add package Microsoft.Identity.Web.DownstreamApi dotnet add package Microsoft.Identity.Web.AgentIdentities在 appsettings.json中配置令牌凭据选项和 API。
{ "AzureAd": { "Instance": "https://login.partner.microsoftonline.cn/", "TenantId": "your-tenant-id", "ClientId": "your-blueprint-id", "ClientCredentials": [ { "SourceType": "ClientSecret", "ClientSecret": "your-client-secret" } ] }, "DownstreamApis": { "MyApi": { "BaseUrl": "https://api.example.com", "Scopes": ["api://my-api-client-id/read", "api://my-api-client-id/write"], "RelativePath": "/api/v1", "RequestAppToken": false } } }配置服务以添加下游 API 支持:
using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.Identity.Web; var builder = WebApplication.CreateBuilder(args); // Add authentication builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches(); // Register downstream APIs builder.Services.AddDownstreamApis( builder.Configuration.GetSection("DownstreamApis")); // Add Agent Identities support builder.Services.AddAgentIdentities(); builder.Services.AddControllersWithViews(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();使用
IDownstreamApi.. 调用受保护的 API。 调用 API 时,可以使用WithAgentIdentity方法或WithAgentUserIdentity方法指定代理标识或代理的用户帐户标识。IDownstreamApi自动处理令牌获取并将访问令牌附加到请求。对于
WithAgentIdentity,您可以使用仅限应用程序的令牌(自治代理)或代表用户的令牌(交互式代理)来调用 API。using Microsoft.Identity.Abstractions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; [Authorize] public class ProductsController : Controller { private readonly IDownstreamApi _api; public ProductsController(IDownstreamApi api) { _api = api; } // GET request for app only token scenario for agent identity public async Task<IActionResult> Index() { string agentIdentity = "<your-agent-identity>"; var products = await _api.GetForAppAsync<List<Product>>( "MyApi", "products", options => options.WithAgentIdentity(agentIdentity)); return View(products); } // GET request for on-behalf of user token scenario for agent identity public async Task<IActionResult> UserProducts() { string agentIdentity = "<your-agent-identity>"; var products = await _api.GetForUserAsync<List<Product>>( "MyApi", "products", options => options.WithAgentIdentity(agentIdentity)); return View(products); } }对于
WithAgentUserIdentity,可以指定用户主体名称(UPN)或对象标识(OID)来标识代理的用户帐户。using Microsoft.Identity.Abstractions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; [Authorize] public class ProductsController : Controller { private readonly IDownstreamApi _api; public ProductsController(IDownstreamApi api) { _api = api; } // GET request for agent's user account identity using UPN public async Task<IActionResult> Index() { string agentIdentity = "<your-agent-identity>"; string userUpn = "user@contoso.com"; var products = await _api.GetForUserAsync<List<Product>>( "MyApi", "products", options => options.WithAgentUserIdentity(agentIdentity, userUpn)); return View(products); } // GET request for agent's user account identity using OID public async Task<IActionResult> UserProducts() { string agentIdentity = "<your-agent-identity>"; string userOid = "user-object-id"; var products = await _api.GetForUserAsync<List<Product>>( "MyApi", "products", options => options.WithAgentUserIdentity(agentIdentity, userOid)); return View(products); } }