如何在.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);
你之前代码的错误点
- ID误用:直接使用App注册的Client ID(0002)访问
ServicePrincipals["0002"],但ServicePrincipal的ID和App注册的Client ID是完全不同的两个值,这是导致Request_ResourceNotFound错误的核心原因。 - 参数填反:
PrincipalId和ResourceId的对应关系搞反了——PrincipalId应该是客户端的ServicePrincipal ID,ResourceId是API的ServicePrincipal ID。 - 操作错误:使用
GetAsync查询现有权限分配,而不是用PostAsync执行新的权限授予操作。
内容的提问来源于stack exchange,提问作者Mlo
相关产品推荐
相关产品推荐

