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

如何在.NET Core 7的C#中通过MS Graph授予AppReg的API权限

解决方案:通过MS Graph完成App注册的API权限授予

首先明确:你代码里的RequiredResourceAccess只是声明该App注册需要的权限,并不会自动完成权限授予。实际的权限授予需要通过操作ServicePrincipal的AppRoleAssignments来实现,且要注意几个关键ID的对应关系:

关键ID说明

  • PrincipalId:你创建的App注册(Client ID 0002)对应的服务主体(ServicePrincipal)ID(注意:不是App注册的Client ID)
  • ResourceId:目标API(Client ID 0001)对应的服务主体(ServicePrincipal)ID(不是API的Client ID)
  • AppRoleId:要授予的API角色ID(0003)

修正后的完整流程代码

1. 创建App注册(保留你的原有代码)

GraphServiceClient graphClient = await GetGraphServiceClientAsync();
Application requestBody = new()
{
    DisplayName = "MyNewAppReg",
    Description = "MyNewAppReg - created by me",
    RequiredResourceAccess = new List<RequiredResourceAccess>
    {
        new()
        {
            ResourceAppId = "0001", // API的Client ID
            ResourceAccess = new List<ResourceAccess>
            {
                new()
                {
                    Id = Guid.Parse("0003"), // 目标角色ID
                    Type = "Role"
                }
            }
        }
    }
};
Application? appResult = await graphClient.Applications.PostAsync(requestBody);

2. 获取客户端App注册对应的ServicePrincipal

创建Application后,Azure会自动生成对应的ServicePrincipal,你可以通过App的ClientId查询到它:

// 查询客户端App对应的ServicePrincipal
var clientSpResponse = await graphClient.ServicePrincipals
    .GetAsync((requestCfg) =>
    {
        requestCfg.QueryParameters.Filter = $"appId eq '{appResult.AppId}'";
    });
var clientSpId = clientSpResponse.Value.First().Id;

3. 获取目标API对应的ServicePrincipal

同样,通过API的Client ID查询它的ServicePrincipal:

// 查询目标API对应的ServicePrincipal
var apiSpResponse = await graphClient.ServicePrincipals
    .GetAsync((requestCfg) =>
    {
        requestCfg.QueryParameters.Filter = $"appId eq '0001'";
    });
var apiSpId = apiSpResponse.Value.First().Id;

4. 执行权限授予(创建AppRoleAssignment)

注意是用PostAsync创建分配,不是GetAsync:

var permissionAssignment = new AppRoleAssignment
{
    PrincipalId = Guid.Parse(clientSpId), // 客户端ServicePrincipal ID
    ResourceId = Guid.Parse(apiSpId),     // API的ServicePrincipal ID
    AppRoleId = Guid.Parse("0003")        // 要授予的角色ID
};

// 对客户端ServicePrincipal添加权限分配
await graphClient.ServicePrincipals[clientSpId].AppRoleAssignments
    .PostAsync(permissionAssignment);

你之前代码的错误点

  1. ID误用:直接使用App注册的Client ID(0002)访问ServicePrincipals["0002"],但ServicePrincipal的ID和App注册的Client ID是完全不同的两个值,这是导致Request_ResourceNotFound错误的核心原因。
  2. 参数填反:PrincipalId和ResourceId的对应关系搞反了——PrincipalId应该是客户端的ServicePrincipal ID,ResourceId是API的ServicePrincipal ID。
  3. 操作错误:使用GetAsync查询现有权限分配,而不是用PostAsync执行新的权限授予操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:43:20