如何使用 Microsoft Graph 和 SDK 更新现有 B2C 用户的身份集合

How to update identities collection for existing B2C User using Microsoft Graph and SDK

我正在尝试为 Azure AD B2C 租户中的现有用户更新 identities 集合。具体来说,我正在尝试为用户添加另一个 federated 身份条目。

根据 Microsoft Graph documentation 这应该是可能的,前提是我:

  1. 向我用来调用图形的客户端分配 User.ManageIdentities.All 权限
  2. 发送整个现有身份集合,并附加新的身份条目(这也确保在请求中发送具有 signInType userPrincipalName 的现有身份)

我已经在 B2C 租户中注册了一个应用程序并为其分配了访问 Microsoft Graph 的特定权限。我正在使用客户端凭据流来获取具有 roles 声明中适当权限的访问令牌。我可以成功获取访问令牌,并通过检查颁发的 JWT 确认存在所需的权限。

我还使用 Microsoft.Graph SDK 从 C# 代码调用图形 v1.0 端点。我有一个我正在尝试更新的现有用户,它具有众所周知的 userId (objectId)。使用访问令牌和 GraphServiceClient 我可以成功检索用户。例如,下面的代码工作正常

var user = await client.Users[userId].Request()
    .Select(o => new { o.Id, o.DisplayName, o.Identities })
    .GetAsync();

检索用户后,我尝试为用户添加另一个条目到 identities 属性 并为用户发出更新图调用。请注意,SDK 需要更新调用才能仅使用本地创建的对象,即您不能发送之前通过 SDK 获取的现有对象。

我的完整更新代码如下

async Task TryUpdateUser(GraphServiceClient client, string userId)
{
    var user = await client.Users[userId].Request()
        .Select(o => new { o.Id, o.DisplayName, o.Identities })
        .GetAsync();

    // Need to re-create the existing identities since Graph client rejects existing items in requests
    var identities = user.Identities.Select(o => new ObjectIdentity 
    {
        SignInType = o.SignInType,
        Issuer = o.Issuer,
        IssuerAssignedId = o.IssuerAssignedId
    }).ToList();

    identities.Add(new ObjectIdentity
    {
        SignInType = "federated",
        Issuer = "TestIssuer",
        IssuerAssignedId = "testingId"
    });

    var updatedUser = new User
    {
        Identities = identities
    };

    await client.Users[userId].Request().UpdateAsync(updatedUser);
}

但是,当调用 UpdateAsync 时,将抛出响应类型为 BadRequest 的异常。错误消息指出:

Message: Adding a non-federated user signInType is not permitted if the user only has social/federated identities or no identities set. Please recreate the user with a non-federated identity along with existing identities if any.

我显然正在尝试创建 federated 用户 signInType,因此错误消息文本指的是 non-federated 用户 signInType让我感到困惑。

我做错了什么?

目前,我们无法将 Azure AD b2c 联合用户从一个身份提供者迁移到另一个身份提供者,也无法为 Azure AD b2c 联合用户添加另一个身份提供者或非联合身份(用户名或电子邮件地址)。如果您尝试这样做,您将收到如上所示的错误。

此外,请注意我们可以为 Azure AD b2c 本地用户添加一个身份提供程序。

正如已接受的答案所指出的,Microsoft Graph 当前不支持更新现有联合用户以添加其他联合身份 API。

但是,可以改用 Azure AD Graph API 来执行此操作。有关可用的用户更新选项,请参阅 Azure AD Graph API Update User documentation

假设我们有一个 userId 我们想要更新,您需要执行以下操作:

  1. 通过向 https://graph.windows.net/{tenant}/users/{userId}/userIdentities?api-version=1.6
  2. 发出 GET 请求来检索用户现有的 userIdentities
  3. 向现有身份添加另一个 UserIdentity 条目 - 重要的是,当您指定 issuerUserId 值时,它必须是 base64 编码的
  4. 向位于 https://graph.windows.net/{tenant}/users/{userId}?api-version=1.6 的基本用户端点发送 PATCH 请求 - 您发送的内容只是一个带有单个 userIdentities 属性 的 JSON 对象包含现有和新添加的身份的数组

通过 AAD Graph API 发出 PATCH 请求后,可以使用 Microsoft Graph API 查询更新的用户并确认已将附加条目添加到 identities 合集 SignInType,共 federated