如何在多租户环境中配置代表身份验证?

How to configure on-behalf-of authentication in multi-tenant environment?

我有一个调用我编写的服务的本机客户端——它又调用图形 API(使用原始调用者的凭据)。

这与此处找到的 'onbehalfof' 示例完全一样(我的代码失败的方式与示例相同):

https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof

当以与服务相同的租户(租户 A)的用户身份登录时,一切正常(就像样本的代表)。当以来自不同租户(租户 B)的用户身份登录时,我在服务的这一行出现异常:

result = await authContext.AcquireTokenAsync(GraphResourceId, clientCred, userAssertion);

(这是 onbehalfof 示例中 TodoListController.cs 的第 153 行)。

例外情况是:

AADSTS65001: The user or administrator has not consented to use the application with ID 'de2fb28b-83f8-419d-9b00-3fbce0a60bf4'. Send an interactive authorization request for this user and resource.\r\nTrace ID: 6865c420-674a-4adf-a070-3d9b9c500200\r\nCorrelation ID: 7e088563-d7fe-4131-a05c-cbe04dbb2bbd\r\nTimestamp: 2017-03-29 22:56:58Z

上面的application id指的是我写的服务(和onbehalfofsample中TodoListService中的同一行)

我为多租户身份验证配置了一切。但导致问题的是我的服务对另一个服务(图 API)进行的 附加 调用。我需要在 Azure 门户中进行哪些额外配置才能使其正常工作?

在为上面链接的示例编写的说明中,他们通过以下部分解决了这个问题:

Configure known client applications

For the middle tier web API to be able to call the downstream web API, the user must grant the middle tier permission to do so in the form of consent. Because the middle tier has no interactive UI of its own, you need to explicitly bind the client app registration in Azure AD with the registration for the web API, which merges the consent required by both the client & middle tier into a single dialog. You can do so by adding the "Client ID" of the client app, to the manifest of the web API in the knownClientApplications property. Here's how:

  1. Navigate to your 'TodoListService' app registration, and open the manifest editor.
  2. In the manifest, locate the knownClientApplications array property, and add the Client ID of your client application as an element.

    Your code should look like the following after you're done: "knownClientApplications": ["94da0930-763f-45c7-8d26-04d5938baab2"]

  3. Save the TodoListService manifest by clicking the "Save" button.

我的假设是,因为您 运行 遇到了这个问题,所以您没有进行此特殊配置。

您的另一个选择是明确请求中间层和 AAD 图之间的同意 API。您可以通过聘请租户管理员 'login' 并同意您的中间层服务来做到这一点。您需要做的就是使用中间层 App ID 生成一个登录 url。

但是,我强烈建议您按照记录的方式进行操作,因为这将为您的用户提供更好的体验。

这是其他租户的用户登录时出现的同意对话框:

Consent Dialog

这是我的客户清单...

Client Manifest

...和我的服务清单...

Service Manifest

现在可以了。我必须进行两项更改才能使其正常工作。

首先,在服务端切换到使用"common"作为租户。我已经在客户端切换到 common 但没有意识到您也必须在服务端执行此操作:

<add key="ida:Tenant" value="common" />

其次,将服务上的 GraphUserUrl 更改为以下 URL:

<add key="ida:GraphUserUrl" value="https://graph.windows.net/me?api-version=1.6" />

示例中的原始 URL 不起作用(至少对于另一个租户中的用户而言)。