使用托管标识在另一函数应用中调用HTTP触发的函数应用
使用系统托管标识验证函数应用间的HTTP调用
一、配置目标函数应用(被调用端)
- 启用系统托管标识
进入Azure门户的目标函数应用,找到「标识」>「系统分配」,将状态设为「开启」后保存。 - 配置身份验证规则
进入「身份验证」>「添加身份验证提供程序」,选择「Microsoft」作为提供程序:- 允许的令牌受众:填入目标函数应用的系统托管标识客户端ID,格式为
api://<客户端ID>;或直接使用函数应用的应用ID URI。 - 未经过身份验证的请求:设置为「HTTP 401 未经授权」,确保仅验证通过的请求可访问。
- 允许的令牌受众:填入目标函数应用的系统托管标识客户端ID,格式为
- 调整触发器授权级别
在目标函数的function.json中,将authLevel设为anonymous——因为我们依赖Azure AD身份验证拦截未授权请求,无需保留函数级别的密钥验证。
二、配置源函数应用(调用端)
- 启用系统托管标识
同目标端操作,在Azure门户开启源函数应用的系统托管标识并保存。 - 授予访问权限
- 找到目标函数应用对应的Azure AD企业应用(可通过目标函数的客户端ID在Azure AD中搜索)。
- 进入源函数应用的托管标识对应的服务主体(Azure AD>企业应用>搜索源函数名称),添加API权限:
选择「我的组织使用的API」,搜索目标函数应用名称/客户端ID,勾选user_impersonation权限后完成添加。
三、源函数应用代码实现(.NET 6独立进程)
- 先安装
Azure.IdentityNuGet包,用于获取托管标识令牌。 - 示例函数代码:
using System.Net.Http.Headers; using Azure.Identity; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Logging; namespace SourceFunctionApp { public class CallTargetFunction { private readonly HttpClient _httpClient; private readonly DefaultAzureCredential _credential; // 替换为目标函数的实际URL private readonly string _targetFunctionUri = "https://<target-function-app>.azurewebsites.net/api/<target-function-name>"; // 替换为目标函数应用的系统托管标识客户端ID private readonly string _targetClientId = "<target-function-client-id>"; public CallTargetFunction(HttpClient httpClient) { _httpClient = httpClient; _credential = new DefaultAzureCredential(); } [Function("CallTargetFunction")] public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext executionContext) { var logger = executionContext.GetLogger("CallTargetFunction"); // 获取访问目标函数的Bearer令牌 var tokenContext = new TokenRequestContext(new[] { $"api://{_targetClientId}/.default" }); var tokenResult = await _credential.GetTokenAsync(tokenContext); // 构建请求并添加令牌 var request = new HttpRequestMessage(HttpMethod.Post, _targetFunctionUri); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.Token); // 若需传递请求体,添加以下代码: // request.Content = new StringContent("{\"key\":\"value\"}", System.Text.Encoding.UTF8, "application/json"); var response = await _httpClient.SendAsync(request); // 返回响应结果 var responseData = req.CreateResponse(response.StatusCode); await responseData.WriteStringAsync(await response.Content.ReadAsStringAsync()); return responseData; } } }
关键注意事项
- 两个函数应用必须处于同一Azure租户,否则托管标识无法跨租户验证。
- 若调用时返回403错误,检查源函数的托管标识是否已正确授予目标函数的
user_impersonation权限。 - 本地开发时,
DefaultAzureCredential会自动使用Azure CLI、Visual Studio等本地登录身份获取令牌,无需额外配置。
内容的提问来源于stack exchange,提问作者AJames
相关产品推荐
相关产品推荐

