C# 如何使用Azure Active Directory图形API获取属于某个AppRole的所有用户

C# 如何使用Azure Active Directory图形API获取属于某个AppRole的所有用户,c#,azure,azure-active-directory,C#,Azure,Azure Active Directory,我一辈子都搞不懂如何查询Azure Active Directory的Graph API来获取属于某个特定应用程序的所有用户 首先,我尝试了以下方法: client.Users.Where(u => u.AppRoleAssignments.Any(r => r.Id == "some-guid")); 但这不会编译,因为ApprovaliseSignments是一个IPagedCollection,所以您不能在它上执行类似.Any的操作 然后,我尝试为我的应用程序查询Servic

我一辈子都搞不懂如何查询Azure Active Directory的Graph API来获取属于某个特定应用程序的所有用户

首先,我尝试了以下方法:

client.Users.Where(u => u.AppRoleAssignments.Any(r => r.Id == "some-guid"));
但这不会编译,因为ApprovaliseSignments是一个IPagedCollection,所以您不能在它上执行类似.Any的操作

然后,我尝试为我的应用程序查询ServicePrincipal中的所有批准:

var servicePrincipal = await client.ServicePrincipals
    .Expand(p => p.AppRoleAssignments)
    .Where(p => p.AppId == "my app id guid")
    .ExecuteSingleAsync();
但是
servicePrincipal.approvalsignments
顽固地返回为空,似乎忽略了我的.Expand

我还尝试通过ID直接获取ServicePrincipal并进行扩展:

var principal = await client.ServicePrincipals
    .GetByObjectId("feeaae9c-40a3-48a3-8a01-b87343f5ecfc")
    .Expand(p => p.AppRoleAssignments)
    .ExecuteAsync();
但这只会导致一个错误(如果删除.Expand,错误就会消失):

这是一个奇怪的错误,因为错误消息中的对象id以“()”作为后缀,而我的代码没有添加该后缀


我错过了什么明显的东西吗?当然有一种简单的方法可以让所有用户都满意吗?

我终于找到了答案。为了从ServicePrincipal获得批准,您需要直接查询列表,而不是尝试从ServicePrincipal展开列表:

await client.ServicePrincipals
    .GetByObjectId(servicePrincipalObjectId)
    .AppRoleAssignedTo
    .ExecuteAsync()
然后,您必须手动遍历用户和组,以获得最终的用户列表。这可能会导致许多Graph API服务调用,具体取决于有多少组和用户,因此请注意

编辑:正如Dan Kershaw在评论中提到的,角色仅适用于直接链接到批准的组中的用户。子组不继承角色


我已经把完整的解决方案放在了一个要点中,因为它实在太大了,无法在这里内联。

谢谢您发布这篇文章。我会和我们的工程团队谈谈我们在这个领域可以做的任何改进。您应该注意的一点是,当前对组的可批准分配仅支持单个级别(即不支持嵌套组)。@DanKershaw MSFT感谢您的澄清。我已经从Gist中删除了递归枚举。@DanKershaw MSFT,应用程序角色现在支持嵌套组吗?这仍然是最好的方法吗?@DanKershaw MSFT在这方面有什么改进吗?
await client.ServicePrincipals
    .GetByObjectId(servicePrincipalObjectId)
    .AppRoleAssignedTo
    .ExecuteAsync()