如何在 SPA 应用程序中从 Web API 访问 Graph API

Posted

技术标签:

【中文标题】如何在 SPA 应用程序中从 Web API 访问 Graph API【英文标题】:How to access Graph API from Web API in SPA application 【发布时间】:2016-06-18 14:01:44 【问题描述】:

我有一个与 WebAPI 对话的 Angular 应用程序,并且用户通过 Azure Active Directory 进行身份验证

我遵循https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp-dotnet-webapi 此处的示例,并能够针对 AD 对用户进行身份验证并将其传递给 Web API。

但是我想在 Web API 中访问 Graph API 并获取当前用户配置文件信息。如何设置?

已更新以提供有关设置的更多背景信息:

我有一个托管 htmljavascript 文件的网站 (site.domain1.com),它制作了一个 SPA 应用程序。我在 api.domain2.com 上托管了 Web API。身份验证针对 Azure AD,使用带有 ADAL.js 和 angular-adal 的 OAuth 隐式流。我想在 SPA 中进行身份验证以获取 API 的 accessToken。我希望在 API 中作为查询 Graph API 的请求的一部分,以获取有关当前用户登录的更多信息。

我能够获取 API 的 accessToken 并且它目前会生成 Claims Principal。问题是用我在 Web API 中的当前身份查询 Graph API。

更新:

我不想将管理员权限授予 Web API,但我想将用户同意仅转发给浏览器的“读取用户配置文件”到网站和 Web API。

我使用了与位于此处https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof的样本类似的方法

它适用于我的测试 AD 并且不适用于生产 AD 的问题。说用户需要在使用 Graph Api 之前集中应用程序。(对于生产 AD,我只有用户可以添加用户权限,但不能添加应用程序权限。我的猜测是该方案工作我需要 AD 的全局管理员首先集中)。最终,我最终将用于网站和 Web API 的 Azure AD 应用程序合并在一起,并且它使用了与 Bootstrap Tokens 相同的 On Behalf Of 方法。但我想知道如何让它与 2 个应用程序一起正常工作。

【问题讨论】:

你看到样本了吗:github.com/Azure-Samples/… 是的,我做到了。谢谢链接。不同之处在于,在此示例中,他们从 JavaScript 访问 Graph API,但我想从 Web API 执行此操作。如果我从 JavaScript 访问 Graph API,它也适用于我,但我想从 Web API 执行此操作。 好的,我明白了。我给你提供了一些样品,希望对你有帮助。 @VladimirMakaev,您想使用用户凭据访问 GraphAPI 吗? 我想实现和弗拉基米尔一样的目标。你找到方法了吗? 【参考方案1】:

权限可在 Azure 的应用配置页面中配置,您可以选择要让应用访问的内容。

至于确认,您作为管理员可以选择。用户接受与您的应用共享数据,或者管理员确认租户下的所有人。

这是正确的方法。我的前端和后端都是这样工作的。

【讨论】:

【参考方案2】:

请查看示例:https://github.com/Azure-Samples/active-directory-dotnet-graphapi-web。 示例中有一些访问 Graph API 和获取用户配置文件的代码:

ClientCredential credential = new ClientCredential(clientId, appKey);
AuthenticationResult result = authContext.AcquireTokenSilent(graphResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

// Call the Graph API manually and retrieve the user's profile.
string requestUrl = String.Format(CultureInfo.InvariantCulture, graphUserUrl, HttpUtility.UrlEncode(tenantId));
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);

// Return the user's profile in the view.
if (response.IsSuccessStatusCode) 
    string responseString = await response.Content.ReadAsStringAsync();
    profile = JsonConvert.DeserializeObject<UserProfile>(responseString);

您可以从这里查看更多信息:https://azure.microsoft.com/en-us/documentation/articles/active-directory-code-samples/#calling-azure-ad-graph-api

【讨论】:

谢谢。这个示例并没有真正涵盖我在这里的设置。最大的不同是我有 JavaScript 客户端和 Web API,它们应该是不同的主机,所以 cookie 身份验证不起作用。可能有一种方法可以使 Angular 客户端使用 OpenId Connect 对 Web API 进行身份验证,OpenId Connect 对 Azure AD 进行身份验证,但它需要从 Angular 到 WebApi 是基于令牌的。我会尝试进行更多调查,但对我来说似乎并不紧张 为什么要部署在不同的主机上?我无法完全理解你的意图。如果您在此处提供更多信息,您可以获得更多帮助。谢谢。 好吧,如果我想让我的组件有一个单独的部署周期,我可能想这样做。或者,该 API 可以是通用的并由其他 SPA 应用程序使用。 我有类似的调用 PowrBI API 的用例。我在 server1 上托管了一个 Web API,它应该代表登录用户调用 PowerBI API。用户将登录到受 Azure AD 保护的 Angular 客户端应用程序,并获取受 Azure AD 保护的 API 的访问令牌。此自定义 API 将依次代表此登录用户调用 PowerBI API。请提出建议。【参考方案3】:

所以我知道这是一个旧的,但我只是遇到了它,因为我有同样的问题/设置。它需要一些挖掘,但我认为这个链接可能会帮助那些有同样问题的人。

https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapi-onbehalfof/

这使用 WPF 客户端和具有单独 API 的 SPA,并从 Web API 而非 spa 或客户端调用 Graph API。

祝大家好运。

【讨论】:

链接失效

以上是关于如何在 SPA 应用程序中从 Web API 访问 Graph API的主要内容,如果未能解决你的问题,请参考以下文章

使用 OAuth 访问 SPA 和 REST API 时,应该在哪里为 RBAC 存储用户组成员身份

如何通过 docker 将 API 与 Web SPA 连接起来

如何在asp.net核心中从客户端调用web api方法?

如何在没有 SPA 或图形界面的情况下,仅通过 POSTMAN 访问 Laravel Sanctum 的 API 路由?

如何验证从反应 SPA 中的 keycloak 检索的 nodejs express api 的访问令牌?

如何在自定义 Zapier 应用程序中从 Xero 访问特定订单项值?