You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何动态配置Microsoft Graph API权限?替代Azure门户手动配置

问题

我编写了一个用于测试Microsoft Graph API的基础C#程序,当前通过Azure门户手动配置API调用权限。是否存在更优方案?能否根据代码中新增的API调用动态配置权限,而非手动在Azure门户操作?

代码实现

GraphHandler.cs

public class GraphHandler
{
    public GraphServiceClient GraphClient { get; private set; }

    public GraphHandler(string tenantId, string clientId, string clientSecret)
    {
        GraphClient = CreateGraphClient(tenantId, clientId, clientSecret);
    }
    public GraphServiceClient CreateGraphClient(string tenantId, string clientId, string clientSecret)
    {
        var options = new TokenCredentialOptions
        {
            AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
        };

        var clientSecretCredential = new ClientSecretCredential(
            tenantId, clientId, clientSecret, options);
        var scopes = new[] { "https://graph.microsoft.com/.default" };

        return new GraphServiceClient(clientSecretCredential, scopes);
    }

    public async Task<User?> GetUser(string userPrincipalName)
    {
        return await GraphClient.Users[userPrincipalName].GetAsync();
    }

    public async Task<(IEnumerable<Site>?, IEnumerable<Site>?)> GetSharepointSites()
    {
        var sites = (await GraphClient.Sites.GetAllSites.GetAsync())?.Value;
        if(sites == null)
        {
            return (null, null);
        }

        sites.RemoveAll(x => string.IsNullOrEmpty(x.DisplayName));

        var spSites = new List<Site>();
        var oneDriveSites = new List<Site>();

        foreach (var site in sites)
        {
            if (site == null) continue;
            
            var compare = site.WebUrl?.Split(site.SiteCollection?.Hostname)[1].Split("/");
            if (compare.All(x => !string.IsNullOrEmpty(x)) || compare.Length < 1)
            {
                continue;
            }

            if (compare[1] == "sites" || string.IsNullOrEmpty(compare[1]))
                spSites.Add(site);
            else if (compare[1] == "personal")
                oneDriveSites.Add(site);
        }

        return (spSites, oneDriveSites);
    }
}

Program.cs

string tenantId = "INPUT TENANT ID";
string clientId = "INPUT CLIENT ID";
string clientSecret = "INPUT CLIENT SECRET";

var graphHandler = new GraphHandler(tenantId, clientId, clientSecret);


Console.WriteLine("Get display name of user:");
var user = await graphHandler.GetUser("mail@example.com");
Console.WriteLine(user?.DisplayName);

Console.WriteLine("Get all sharepoint sites in tenant");
var spSites = (await graphHandler.GetSharepointSites()).Item1;
foreach (var site in spSites)
{
    Console.WriteLine(site.DisplayName);
}

Console.ReadLine();
解决方案

首先明确:完全自动动态配置权限是无法实现的,因为Azure AD的权限管理出于安全考虑,要求应用权限必须经过租户管理员授权(委派权限部分场景允许用户自行同意,但应用权限必须管理员确认)。不过可以通过以下方案减少手动操作的繁琐:

1. 用Microsoft Graph API自动化权限配置

你可以编写代码来管理应用注册和权限,前提是执行操作的服务主体拥有Application.ReadWrite.All这类管理应用的权限:

  • 调用POST /applications/{appId}/appRoleAssignments接口为应用添加应用权限
  • 调用POST /servicePrincipals/{spId}/oauth2PermissionGrants接口添加委派权限
  • 注意:添加权限后仍需管理员完成同意操作(可以通过调用对应API或门户完成批量同意)

2. 使用ARM模板标准化应用配置

将应用注册、权限配置写成ARM模板,每次部署时自动创建或更新应用:

  • 在模板的Microsoft.AAD/directoryApplications资源中,通过requiredResourceAccess节点定义需要的Graph权限
  • 新增API调用时,只需修改模板中的权限列表,重新部署即可完成配置,无需手动操作门户

3. 用Azure CLI/PowerShell脚本自动化

编写脚本实现应用注册和权限配置的自动化:

  • 用Azure PowerShell的New-AzADApplication、New-AzADServicePrincipal命令创建应用和服务主体
  • 用New-AzADAppPermission等命令添加所需权限
  • 新增权限时,修改脚本中的权限ID,运行脚本即可完成更新

4. 结合配置文件关联代码与权限

针对你现有代码的优化:

  • 当前使用的https://graph.microsoft.com/.default范围会包含所有已配置的应用权限,所以新增API调用后,只需确保对应权限已配置(手动或自动化方式)
  • 可以将所需权限整理到配置文件(如appsettings.json)中,让自动化脚本读取该配置来添加权限,实现代码与权限配置的联动,新增API时只需更新配置文件和脚本即可

内容的提问来源于stack exchange,提问作者dev4Life

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 18:03:16