Azure AD集成Web API间调用(web-api-app1调用web-api-app2)实现咨询
好的,要实现已集成Azure AD认证的web-api-app1调用web-api-app2的需求,分两种核心场景来处理,取决于你是否需要传递用户上下文:
场景1:无用户上下文的服务间调用(Client Credentials Flow)
这种场景适用于API之间的后台调用(比如定时任务、服务自动同步),不需要关联前端用户身份。
步骤1:配置Azure AD权限
- 登录Azure门户,找到
web-api-app1的应用注册,进入API权限页面 - 点击「添加权限」→ 选择「我的API」找到
web-api-app2 - 勾选
web-api-app2提供的应用权限(注意不是委托权限,应用权限是服务级别的),然后点击「授予管理员同意」(必须完成这一步,否则权限不生效)
步骤2:在web-api-app1中配置令牌获取与API调用
推荐使用Microsoft.Identity.Web库简化Azure AD认证流程:
- 安装NuGet包:
Install-Package Microsoft.Identity.Web - 在
Program.cs中配置认证和下游API客户端:var builder = WebApplication.CreateBuilder(args); // 配置自身API的Azure AD认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration); // 添加调用web-api-app2的HttpClient,自动处理令牌获取 builder.Services.AddHttpClient("web-api-app2-client", client => { client.BaseAddress = new Uri("https://your-web-api-app2-base-url/"); }) .AddMicrosoftIdentityWebApiAuthentication(builder.Configuration, "DownstreamApi"); var app = builder.Build(); // ... 其他中间件配置 - 在
appsettings.json中添加下游API配置:"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "<你的租户ID>", "ClientId": "<web-api-app1的客户端ID>", "ClientSecret": "<web-api-app1的客户端密钥>", // 生产环境建议用证书替代密钥 "Audience": "<web-api-app1的受众(应用ID URI)>" }, "DownstreamApi": { "BaseUrl": "https://your-web-api-app2-base-url/", "Scopes": "api://<web-api-app2的客户端ID>/你的自定义应用权限范围" } - 在控制器中调用web-api-app2:
[ApiController] [Route("api/[controller]")] public class TestController : ControllerBase { private readonly IHttpClientFactory _httpClientFactory; public TestController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } [HttpGet("call-api2")] public async Task<IActionResult> CallApi2() { var client = _httpClientFactory.CreateClient("web-api-app2-client"); var response = await client.GetAsync("api/your-target-endpoint"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); return Ok(content); } return StatusCode((int)response.StatusCode); } }
步骤3:确保web-api-app2接受令牌
web-api-app2的Azure AD配置需确保:
Audience设置为自身的应用ID URI或客户端ID- 验证逻辑允许来自
web-api-app1的应用权限令牌
场景2:带用户上下文的调用(On-Behalf-Of Flow)
如果需要以当前前端用户的身份,从web-api-app1调用web-api-app2(比如用户发起请求到app1,app1需要以该用户身份调用app2获取数据),则使用OBO流。
步骤1:配置Azure AD权限
- 同样在
web-api-app1的应用注册中,添加web-api-app2的委托权限,并授予管理员同意 - 确保
web-api-app2已在「公开API」页面暴露了对应的委托权限范围
步骤2:在web-api-app1中配置OBO令牌获取
- 同样使用
Microsoft.Identity.Web,在Program.cs中修改配置:builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration) .EnableTokenAcquisitionToCallDownstreamApi() // 启用OBO流支持 .AddInMemoryTokenCaches(); // 缓存令牌提升性能 builder.Services.AddHttpClient("web-api-app2-client", client => { client.BaseAddress = new Uri("https://your-web-api-app2-base-url/"); }) .AddMicrosoftIdentityWebApiAuthentication(builder.Configuration, "DownstreamApi"); appsettings.json的DownstreamApi配置改为委托权限范围:"DownstreamApi": { "BaseUrl": "https://your-web-api-app2-base-url/", "Scopes": "api://<web-api-app2的客户端ID>/你的自定义委托权限范围" }- 控制器中调用API(自动以当前用户身份获取令牌):
[HttpGet("call-api2-as-user")] public async Task<IActionResult> CallApi2AsCurrentUser() { var client = _httpClientFactory.CreateClient("web-api-app2-client"); var response = await client.GetAsync("api/your-target-endpoint"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); return Ok(content); } return StatusCode((int)response.StatusCode); }
关键注意事项
- 生产环境优先使用证书替代客户端密钥,提升安全性:在Azure AD应用注册的「证书和密码」页面上传证书,代码中配置证书路径即可
- 确保
web-api-app2的验证逻辑正确检查令牌的iss(签发者)、aud(受众)和权限声明(roles对应应用权限,scp对应委托权限) - 令牌缓存:使用
AddInMemoryTokenCaches或分布式缓存(如Redis)避免频繁向Azure AD请求令牌
内容的提问来源于stack exchange,提问作者user584018
相关产品推荐
相关产品推荐

