如何在Microsoft Graph API C#中通过电子邮件地址获取用户ID

20

我想将用户添加到一个组中,但我没有用户的id,我只有电子邮件地址。

这里是代码:

User userToAdd = await graphClient
    .Users["objectID"]
    .Request()
    .GetAsync();

await graphClient
    .Groups["groupObjectID"]
    .Members
    .References
    .Request()
    .AddAsync(userToAdd);

请问有人能帮我通过Microsoft Graph从电子邮件地址中检索ObjectId(用户ID)吗?

7个回答

14

您可以通过几种不同的方式查找用户。

/users终结点,您可以使用他们的id(分配给每个帐户的GUID)或者他们的userPrincipalName(默认域的电子邮件别名):

// Retrieve a user by id
var user  = await graphClient
    .Users["00000000-0000-0000-0000-000000000000"]
    .Request()
    .GetAsync();

// Retrieve a user by userPrincipalName
var user  = await graphClient
    .Users["user@tenant.onmicrosoft.com"]
    .Request()
    .GetAsync();

如果您正在使用 授权码或隐式 OAuth 授予,您还可以通过 /me 终结点查找已经认证的用户:

var user = await graphClient
    .Me
    .Request()
    .GetAsync();

有没有一种方法可以按用户主体名称进行过滤? - Tassisto
用户主体名称(User Principal Name)对于租户是唯一的,因此通过 UPN 进行过滤将生成一个仅包含单个项的集合。该项与 .Users["user@tenant.onmicrosoft.com"] 相同。 - Marc LaFleur
2
这不是 OP 所询问的内容。电子邮件地址可以与 UPN 不同,并且不一定是唯一的,遗憾地。 - Pieter Heemeryck

12
除了上面的正确答案之外。 userPrincipalNameid不是外部电子邮件地址。当手动完成注册时,这是我的情况。您可以使用此筛选器:
var user = await _graphClient.Users
    .Request()
    .Filter($"identities/any(c:c/issuerAssignedId eq '{email}' and c/issuer eq 'contoso.onmicrosoft.com')")
    .GetAsync();

来源: https://learn.microsoft.com/zh-cn/graph/api/user-list?view=graph-rest-1.0&tabs=csharp

使用此配置创建用户:

Microsoft.Graph.User graphUser = new Microsoft.Graph.User
{
    AccountEnabled = true,
    PasswordPolicies = "DisablePasswordExpiration,DisableStrongPassword",
    PasswordProfile = new PasswordProfile
    {
            ForceChangePasswordNextSignIn = false,
            Password = accountModel.Password,
        },
        Identities = new List<ObjectIdentity>
        {
            new ObjectIdentity()
            {
                SignInType = "emailAddress",
                Issuer ="contoso.onmicrosoft.com",
                IssuerAssignedId = email
            }
        },
};

已弃用,Request()不再存在。 - Luca Ziegler

2

您可以使用 iduserPrincipalName(即电子邮件地址)从 Graph API 检索用户详细信息。

来自Microsoft Graph API 参考文档

GET /users/{id | userPrincipalName}

你尝试过将电子邮件地址作为objectID使用吗?


1
OP 正在请求提供邮箱,而不是 UPN 或 ID。 邮箱地址不一定与 UPN 相同。 - Pieter Heemeryck

1
如果您需要检索一个“访客用户”,可以使用以下代码:

public static async Task<User> GetGuestUserByEmail(string email)
{
        try
        {
            var request = await graphClient
                .Users
                .Request()
                .Filter($"userType eq 'guest' and mail eq '{email}'") // apply filter
                .GetAsync();

            var guestUsers = request.CurrentPage.ToList();
            var user = guestUsers.FirstOrDefault();
            return user;
        }
        catch (ServiceException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
            return null;
        }
 }

1
实际上,没有一种真正可靠的方法来做到这一点。AAD中的电子邮件地址并不唯一。UPN通常是电子邮件地址,它是唯一的,但有一个令人讨厌的问题:如果该人员恰好拥有长电子邮件地址,并且他们是来宾用户,则UPN似乎是将电子邮件截断为54个字符,然后添加#EXT#,甚至可以在事后更改以删除#EXT#,在@符号之前最多可以达到64个字符,并且不必与其实际电子邮件地址相似。
你唯一能找到他们的方法是使用他们的用户对象GUID。
参考链接:https://learn.microsoft.com/en-us/answers/questions/81053/user-principal-name-and-ext.html

0

使用 Open ID 机制可以可靠地获取电子邮件地址。使用 openid 作为范围,您可以从 https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration 获取 userinfo_endpoint 端点。

GET https://graph.microsoft.com/oidc/userinfo (this endpoint shouldn't be hard coded)

{
 "sub": "uniqueid",
  "name": "Name",
  "family_name": "Name",
  "given_name": "Name",
  "picture": "https://graph.microsoft.com/v1.0/me/photo/$value",
  "email": "email@example.com"
}

https://learn.microsoft.com/en-us/azure/active-directory/develop/userinfo


0

这是一个看似简单却又非常复杂的事情。我的策略是:

var users = await graphClient.Users.Request()
   .Filter($"userPrincipalName eq '{targetEmail}' or mail eq '{targetEmail}'")
   .GetAsync();

如果你只有电子邮件地址,那么你无法避免可能会出现多个结果,只能让用户选择正确的一个。这是有道理的,因为如果你在 Azure 门户或 DevOps 中添加人员,情况也是一样的。

但至少这样做可以在一个查询中涵盖你的内部用户(通过 userPrincipalName)和访客(通过 mail)。


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