【问题标题】:Get all the users from multi-tenant AD Application using graph API使用图形 API 从多租户 AD 应用程序中获取所有用户
【发布时间】:2019-10-31 02:20:34
【问题描述】:

我正在尝试使用图形 API 为多租户应用程序获取所有用户。为此,我使用请求生成了访问令牌:

POST https://login.microsoftonline.com/common/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials

注意:请注意,在上述请求中,我使用了common 代替了{tenantID}。这只是一个成功的尝试,因为在doc 中为 adminConsent 提出了同样的建议。

通过使用上面生成的访问令牌,我请求用户 API 并收到以下错误

{
    "error": {
        "code": "Authorization_IdentityNotFound",
        "message": "The identity of the calling application could not be established.",
        "innerError": {
            "request-id": "56141b7d-dd5e-44b1-9395-cd15d02b52de",
            "date": "2019-06-17T12:42:19"
        }
    }
}

当我使用租户 ID 生成令牌时,它只返回一个活动目录的用户。

任何人都可以建议,我要去哪里错了吗?

【问题讨论】:

    标签: azure active-directory multi-tenant onedrive azure-ad-graph-api


    【解决方案1】:

    由于您使用的是通用端点,因此您不能在此处使用客户端凭据流(无需用户即可访问)。你需要参考这个document(代表用户获取访问权限)。

    注意:当您使用授权码授权流程(代表用户获取访问权限)时,您需要授予委派权限而不是应用程序权限。

    获取访问令牌

    【讨论】:

    • 我使用了上面提供的方法,但仍然无法获取第二个活动目录的用户。但是如果第二个活动目录中的用户尝试登录我的应用程序,他/她可以这样做。
    • @mohitsharma 如果您的令牌中没有 User.Read.All,您需要将您的范围标识为 https://graph.microsoft.com/User.Read.All
    • 抱歉回复晚了,我正在等待其他租户管理员提供管理员同意。之后,试过了,但反应还是一样。我解码了 Toke,scp 就像"scp": "Files.ReadWrite Files.ReadWrite.All Group.ReadWrite.All IdentityProvider.Read.All Mail.Read profile User.Read User.Read.All User.ReadBasic.All openid email"
    • 我没有收到任何错误,它只是返回一个广告上的用户。
    • @mohitsharma 是的,这是预期的结果。您是否要从所有授予管理员许可的 AD 租户中获取用户?
    【解决方案2】:

    在多租户应用程序中,服务主体对象在访问应用程序的每个租户中创建。这些服务主体对象将持有特定于该租户的同意(用户/管理员)对象,并且机密也链接到这些对象。

    因此,当您获得令牌时,它始终是特定于租户的,您需要为每个租户获取单独的令牌才能在该租户中执行任何操作。

    示例:假设您在租户 A 中注册了一个多租户应用程序,并且还被租户 B、C 和 D 使用。这也会在租户 B、C 和 D 中创建 SP 对象。

    因此,如果您需要在租户 B 中执行任何操作,则需要 SP B 的令牌并使用与其关联的密钥。

    简而言之,如果您想在应用程序的上下文中执行这些操作,您需要所有租户的信任。

    【讨论】:

      【解决方案3】:

      我最近不得不实施这个,在那方面取得了成功。这些是我已经完成的步骤。

      1. 创建了一个多租户应用程序
      2. 授予应用程序权限
      3. 使用特定于租户的身份验证标头配置 GraphClient。

      这是获取特定租户图形客户端的代码。

      private ClientCredentialProvider GetGraphAuthProvider(Guid tenantId) {
                  IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                      .Create(_configuration["AzureAd:ClientId"])
                      .WithTenantId(Convert.ToString(tenantId))
                      .WithClientSecret(_configuration["AzureAd:ClientSecret"])
                      .Build();
                  return new ClientCredentialProvider(confidentialClientApplication);
              }
      
              public GraphServiceClient GetGraphServiceClient(Guid tenantId) = >new GraphServiceClient(GetGraphAuthProvider(tenantId));
          }
      }
      

      我已经在my blog here中解释了一切。

      【讨论】:

        【解决方案4】:

        我看到您正在尝试使用 "common" 获取应用级访问令牌,并且您没有在请求中的任何位置指定租户 ID。您可以在 url 中指定租户 ID:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token,也可以在请求正文中指定它。在这种情况下,您的请求应如下所示:

        POST https://login.microsoftonline.com/common/oauth2/v2.0/token HTTP/1.1
        Host: login.microsoftonline.com
        Content-Type: application/x-www-form-urlencoded
        
        client_id={client Id}
        &scope={scopes, in your case ".default"}
        &client_secret={client secret}
        &tenant_id={organization's tenant id}
        &grant_type=client_credentials
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-09-11
          • 1970-01-01
          • 1970-01-01
          • 2020-06-09
          • 2020-07-25
          • 2017-07-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多