如何通过托管标识让租户A的多租户Azure函数访问租户B的Graph API
实现租户A的Azure函数用托管身份访问租户B的Microsoft Graph
可行性确认
完全可以通过托管身份(系统分配或用户分配)替代客户端密钥实现跨租户访问,核心是在租户B中为租户A的托管身份创建服务主体并授予对应权限。
步骤指导
1. 为Azure函数配置托管身份
- 系统分配托管身份:在Azure门户的函数应用→身份→系统分配→开启,保存后记录生成的对象ID和应用程序ID。
- 用户分配托管身份:先创建用户分配的托管身份(Azure门户→托管身份→新建),再在函数应用→身份→用户分配→添加该身份,记录其对象ID和应用程序ID。
2. 在租户B中创建托管身份的服务主体
托管身份默认仅存在于租户A,需在租户B中为其创建对应服务主体:
- 使用Azure CLI(需先登录租户B):
az ad sp create --id <托管身份的应用程序ID> - 或使用PowerShell:
New-AzADServicePrincipal -ApplicationId <托管身份的应用程序ID>
3. 在租户B中授予Microsoft Graph应用权限
- 登录租户B的Azure门户,进入Azure Active Directory→企业应用程序,搜索刚创建的服务主体(名称与托管身份一致)。
- 进入该应用→权限→添加权限→选择Microsoft Graph→应用权限→勾选
Directory.Read.All,点击添加权限。 - 点击授予管理员同意(租户B),完成权限授予。
4. 修改C#代码使用托管身份访问租户B的Graph
使用DefaultAzureCredential自动适配本地与云端环境,代码示例:
using Microsoft.Graph; using Azure.Identity; var tenantBId = "<租户B的ID>"; var graphClient = new GraphServiceClient( new DefaultAzureCredential(), new[] { "https://graph.microsoft.com/.default" } ); // 指定租户B获取用户列表 var users = await graphClient.Users .GetAsync(requestConfig => { requestConfig.QueryParameters.Select = new[] { "id", "displayName", "userPrincipalName" }; requestConfig.UrlParameters.Add("tenantId", tenantBId); }); // 处理返回的用户数据 foreach (var user in users.Value) { Console.WriteLine($"{user.DisplayName} ({user.UserPrincipalName})"); }
关键注意事项
- 权限生效延迟:管理员同意权限后,可能需要15-30分钟才能完全生效。
- 本地测试:本地运行时,
DefaultAzureCredential会优先使用Azure CLI、Visual Studio或Azure PowerShell中已登录的身份,确保该身份在租户B拥有对应权限(或直接用租户B的管理员身份登录本地工具)。 - 身份类型选择:如果需要访问多个租户,推荐使用用户分配托管身份,便于跨租户权限管理;系统分配身份仅绑定当前函数应用,也可实现跨租户访问,但权限管理相对单一。
内容的提问来源于stack exchange,提问作者Geoff
相关产品推荐
相关产品推荐

