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

Blazor .NET 8.0中用GraphAPI v5筛选特定AppRole用户的问题

获取分配特定AppRole的用户(Graph API v5 + Blazor .NET 8)

问题背景

在Blazor .NET 8应用中使用Graph API v5,需从Entra ID企业应用中获取分配了指定AppRole的用户列表。组织用户规模超1000人,此前尝试两种方案均不可行:

  • 直接在用户查询中使用appRoleAssignments/any(ar: ar/appRoleId eq {roleIdGuid})过滤,触发OData错误:Microsoft.Graph.Models.ODataErrors.ODataError: Property 'appRoleId' does not exist as a declared property or extension property.,确认该过滤方式不被API支持;
  • 分页拉取所有用户后本地筛选角色ID,耗时超90秒,无法满足性能要求。

解决方案:反向查询AppRoleAssignment资源

Graph API不支持从用户维度过滤关联的AppRole ID,但可以直接查询企业应用的AppRoleAssignment资源,筛选目标角色后关联获取用户信息,大幅提升效率。

实现步骤

  1. 获取关键ID:

    • AppRoleId:从应用注册的「App Roles」中复制目标角色的ID;
    • ServicePrincipalId:从Entra管理中心「企业应用→你的应用→概述」中复制「对象ID」(即企业应用的服务主体ID)。
  2. 查询符合条件的AppRoleAssignment:
    直接查询目标企业应用下所有分配了指定角色的主体ID,同时可过滤仅保留用户类型的主体。

  3. 批量获取用户信息:
    收集所有符合条件的用户ID后,分批次批量查询用户详情,减少请求次数。

代码示例

using Microsoft.Graph;
using Microsoft.Graph.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

public async Task<List<User>> GetUsersWithSpecificAppRoleAsync(GraphServiceClient graphClient, Guid appRoleId, Guid servicePrincipalId)
{
    // 1. 查询所有分配了目标角色的用户AppRoleAssignment
    var appRoleAssignmentsRequest = await graphClient.ServicePrincipals[servicePrincipalId.ToString()]
        .AppRoleAssignments
        .GetAsync(requestConfiguration =>
        {
            requestConfiguration.QueryParameters.Filter = $"appRoleId eq '{appRoleId}' and principalType eq 'User'";
            requestConfiguration.QueryParameters.Select = new[] { "principalId" };
            requestConfiguration.QueryParameters.Top = 999; // 单页最大返回数
        });

    // 2. 遍历分页结果,收集所有用户ID
    var userIds = new List<string>();
    var pageIterator = PageIterator<AppRoleAssignment, AppRoleAssignmentCollectionResponse>
        .CreatePageIterator(graphClient, appRoleAssignmentsRequest, assignment =>
        {
            userIds.Add(assignment.PrincipalId);
            return true;
        });
    await pageIterator.IterateAsync();

    // 3. 批量获取用户信息(一次最多查询20个用户ID)
    var users = new List<User>();
    for (int i = 0; i < userIds.Count; i += 20)
    {
        var batchIds = userIds.Skip(i).Take(20);
        var filter = string.Join(" or ", batchIds.Select(id => $"id eq '{id}'"));

        var batchUsers = await graphClient.Users
            .GetAsync(requestConfiguration =>
            {
                requestConfiguration.QueryParameters.Filter = filter;
                // 按需选择需要的属性,减少数据传输
                requestConfiguration.QueryParameters.Select = new[] { "id", "displayName", "userPrincipalName", "mail" };
            });

        if (batchUsers?.Value != null)
        {
            users.AddRange(batchUsers.Value);
        }
    }

    return users;
}

关键优化点

  • 精准过滤:直接在AppRoleAssignment层面过滤角色ID和主体类型,避免拉取无关数据;
  • 批量查询:分批次获取用户信息,减少API请求次数,提升响应速度;
  • 属性裁剪:仅请求需要的用户属性,降低数据传输量。

权限要求

确保应用已配置以下权限(根据身份验证方式选择Delegated或Application权限):

  • Directory.Read.All:用于读取用户信息;
  • Application.Read.All:用于读取企业应用的服务主体和AppRoleAssignment信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:59:59