微软图表:如何通过个人电子邮件地址查找用户?

5

我有两个可能相关的问题:

问题1:为什么用户的个人电子邮件地址会出现在Azure门户中作为用户主体名称?

问题2:如何通过用户的个人电子邮件地址查找用户?

我将要查找的电子邮件地址是用作登录名的电子邮件地址,因此我希望它应该出现在像signInNames这样的属性中,如下所述。

复现步骤:

登录Azure门户,在任意用户处查看并观察其用户主体名称。请注意,它以个人电子邮件地址的格式显示(joe@somedomain.com)。复制该用户的对象ID。

在代码中,创建一个新的GraphServiceClient,并使用上面步骤中复制的对象ID检索用户。

GraphServiceClient client = GetGraphServiceClient();
User user = await client.Users[userID].Request().GetAsync();

返回的用户对象中,需要注意UserPrincipalName的值并不是在第一步中Azure门户显示的内容。相反,它是一个分配的标识符:cpim_96fe-48b5-88a2-9ac960a6bdab@mydomain.onmicrosoft.com。

尝试使用个人电子邮件地址查找用户 另请参阅:

GraphServiceClient client = GetGraphServiceClient();
IGraphServiceUsersCollectionPage users = await client.Users.Request().Filter("userPrincipalName eq 'joe@somedomain.com'").GetAsync(); // Count = 0
IGraphServiceUsersCollectionPage users = await client.Users.Request().Filter("mail eq 'joe@somedomain.com'").GetAsync(); // Count = 0

根据这个答案的建议,这个也行不通:

IGraphServiceUsersCollectionPage users3 = await client.Users.Request().Filter("signInNames/any(x:x/value eq 'joe@somedomain.com')").GetAsync(); // error Filter not supported.

我的Azure应用程序拥有User.ReadWrite.All权限。但是,我检索到的任何对象的属性值都没有显示我的个人电子邮件地址。

编辑

针对在这里发布的答案,我尝试了这段代码:

// Exact call to graph:
    https://graph.microsoft.com/beta/users?$filter=otherMails/any(id:id%20eq%20'my.name@outlook.com')
    
    Error message:
    
    System.NotSupportedException : The collection type 'Microsoft.Graph.IUserAppRoleAssignmentsCollectionPage' on 'Microsoft.Graph.User.AppRoleAssignments' is not supported.
    
    [Question regarding above error](https://stackoverflow.com/questions/62776361/how-to-use-graph-explorer-sdk)
    
    [Instruction to use GraphClient](https://learn.microsoft.com/en-us/graph/sdks/create-client?tabs=CS)

使用GraphServiceClient,这里是我如何实现你的回答。在两种情况下,调用 graph 都返回用户,但用户的属性未被填充。我的应用程序具有 User.ReadWrite.All、User.ManageIdentities.All、Domain.ReadWrite.All 权限。这是否是权限问题?
    public async Task<User> GetUserByEmailAddress2(string email)
    {
        GraphServiceClient client = GetGraphServiceClient();
        IGraphServiceUsersCollectionPage users = await client.Users.Request().Filter($"otherMails/any(id:id eq '{email}')").GetAsync();
        var nonnullusers = users.Where(x => x.OtherMails?.Any() ?? false).ToList(); // count = 0
        
        users = await client.Users.Request().Filter($"identities/any(id:id/issuer eq 'LeaderAnalytics.onmicrosoft.com' and id/issuerAssignedId eq '{email}')").GetAsync();
        nonnullusers = users.Where(x => x.Id == email).ToList(); // count = 0

        return users[0];
    }

1
你能提供支持这种情况的文档链接吗?有时,如果我们能找到文档或类似的东西,我们就可以让它工作。此外,这是一个Azure B2C场景吗? - Michael Mainer
6个回答

10

当邮箱地址填写在替代邮件 (otherMails 属性) 时,可进行用户搜索:

  • graph.microsoft.com/beta/users?$filter=otherMails/any(id:id eq 'user@example.com')

当邮箱地址填写在登录名 (signInNames 属性) 时,可进行用户搜索:

  • graph.microsoft.com/beta/users?$filter=identities/any(id:id/issuer eq 'xxxx.onmicrosoft.com' and id/issuerAssignedId eq 'user@example.com')

对于其他人尝试增强身份验证的部分,您必须包括发行者,但不能包括signInType。此外,它现在已经在v1.0中可用。 - fei0x

7
当使用C# SDK时,您的调用会是这样的:
var users = await _graphClient.Users.Request()
                .Filter($"identities/any(id:id/issuer eq 'xxx.onmicrosoft.com' and id/issuerAssignedId eq '{emailAddress}')")
                .GetAsync();

1
几天的搜索后,我尝试了多种方法在Graph Explorer中找到了适用于我的情况的答案。
这将获取用户列表并形成逗号分隔的字符串,并将其用作过滤器,或者如果您只想要一个用户,则使用eq运算符。
var userBatchStr = "'user1@domain.com', 'user2@domain.com'";

// Get Multiple Users
var users = this.graphServiceClient.Users
                .Request()
                .Filter($"userPrincipalName in ({userBatchStr})")
                .GetAsync()
                .Result;

// Get Single User
var user = this.graphServiceClient.Users
                .Request()
                .Filter($"userPrincipalName eq 'user1@domain.com'")
                .GetAsync()
                .Result;

1

对我来说,这些解决方案都不起作用。以下是有效方法,前提是需要正确的权限。

我正在使用https://graph.microsoft.com/v1.0作为终端点。

var officeUser = await graph.Users
            .Request()
            .Filter($"mail eq '{emailAddress}'")
            .Select(e => new {
            e.DisplayName,
            e.Mail,
            e.Id
            })
            .GetAsync();

0

请尝试以下这些Graph Calls:

https://graph.microsoft.com/beta/users?$filter=otherMails/any(id:id eq 'user@example.com') https://graph.microsoft.com/beta/users?$filter=identities/any(id:id/issuer eq 'xxxx.onmicrosoft.com' and id/issuerAssignedId eq 'user@example.com')

请通过Graph Explorer登录Global Administrator或User Administrator账户,单击左侧面板上的“登录到Graph Explorer”按钮。还请确保您使用的用户帐户是B2C租户中的成员帐户(通过Azure门户创建,然后单击Azure Active Directory> Users> New User> Create User选项),并且不是访客或已注册用户。

如果可以,请告诉我是否起作用,并确认您是否在相同用户的上下文中从您的代码中进行这些调用。


1
隐式流。这为什么很重要?我能够访问对象的属性。 - user3230660
它检查已登录用户的UPN中的域名后缀以识别租户。这就是为什么进行这些调用的用户应该是该租户中的成员用户,而不是来宾用户或注册用户的原因。 - AmanpreetSingh_msft
好的,谢谢您的解释。我是我的租户中的成员用户。请查看我之前评论中的错误信息。 - user3230660
如果您运行PowerShell cmdlet,get-azureaduser -objectid <object_id_of_user> | fl,您是否看到用户的otherMails属性填充了值? - AmanpreetSingh_msft
我已经在我的初始响应中包含了两个调用: 对于otherMails属性:https://graph.microsoft.com/beta/users?$filter=otherMails/any(id:id eq 'user@example.com') 对于signinName属性:https://graph.microsoft.com/beta/users?$filter=identities/any(id:id/issuer eq 'xxxx.onmicrosoft.com' and id/issuerAssignedId eq 'user@example.com') 如果您在signInName中填写了值,则应使用第二个调用。如果该值在otherMails属性中,则应使用第一个调用。您不能使用针对otherMails属性的调用来搜索signInName。 - AmanpreetSingh_msft
显示剩余7条评论

-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接