如何通过 Graph API 访问其他用户的数据?

How to access another user's data via the Graph API?

使用图表 API 和相关的 authentication/authorization 流程,我如何访问组织中所有用户的数据?此外,多个 organizations/tenants 需要能够使用该应用程序。

举个例子:我有一个应用程序需要从 contoso.onmicrosoft.com 下所有用户的所有日历中读取事件。我希望管理员 jack@contoso.onmicrosoft.com 授权该应用程序,然后该应用程序将能够读取上述数据。使用托管 API 这可以通过模拟轻松完成。

但是,我正尝试对 Graph API 和 OAuth 做同样的事情,但我找不到直接的解决方案,或者我一定遗漏了一些非常明显的东西。我通过 manage.windowsazure.com(多租户)创建了一个应用程序,并将其配置为需要 Microsoft Graph API(所有应用程序和委派权限)。

我做了以下事情:

1) 将 jack@contoso.onmicrosoft.com 指向 https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&redirect_uri=<my redirect url>&client_id=<my client id>

2) Jack 授权应用程序

3) 我回来了:<my redirect url>/?code=<my authorization code>&session_state=<blah>

4) 我发送了一个 POST 请求,如下所示:

POST https://login.microsoftonline.com/common/oauth2/token
Headers: content-type: application/x-www-form-urlencoded

Body:
grant_type=authorization_code&code=<my auth code from step above>
&redirect_uri=<my redirect url>
&client_id=<my client id>
&client_secret=<my client secret>
&resource=https%3A%2F%2Fgraph.microsoft.com%2F

5) 当我执行以下操作时:

GET https://graph.microsoft.com/v1.0/users/jack@contoso.onmicrosoft.com/messages
Headers: Authorization: Bearer <auth token from step #4>

我收到消息的 200 OK 响应。

当我执行以下操作时:

GET https://graph.microsoft.com/v1.0/users/anyotheruser@contoso.onmicrosoft.com/messages
Headers: Authorization: Bearer <auth token from step #4>

我收到 403 禁止响应:

{
    "error": {
        "code": "ErrorAccessDenied",
        "innerError": {
            "date": "2016-06-07T08:47:27",
            "request-id": "5b629e30-e6bd-474d-b3dd-8ce25c5ad1c4"
        },
        "message": "Access is denied. Check credentials and try again."
    }
}

请使用仅限应用程序的身份验证流程(参见 https://graph.microsoft.io/en-us/docs/authorization/app_only)以使用应用程序权限 - 对于令牌请求(第 4 步),您需要传递 grant_type=client_credentials而不是 grant_type=authorization_code.

您引用的 flow/URLs 用于利用委托范围的授权代码流。

A) 如果您希望该应用仅供管理员使用(即访问所有日历),那么您正在使用正确的流程。

B) 如果您希望应用程序在管理员同意后为所有用户工作,您将需要使用应用程序(客户端凭据)流程并使用应用程序范围。这意味着您需要将同意与常规身份验证流程分开。

如需同意,您需要将管理员指向以下 url:

GET https://login.microsoftonline.com/common/oauth2/authorize?resource=https://graph.microsoft.com/&client_id=<YourClientId>&client_secret=<YourClientSecret>&response_type=code&redirectUri=<YourRedirectUri>&prompt=admin_consent

对于身份验证流程,您需要从您的网络服务器进行一次调用:

POST https://login.microsoftonline.com/common/oauth2/token
body resource=https://graph.microsoft.com/&client_id=<YourClientId>&client_secret=<YourClientSecret>&response_type=code

或者更好的是,只需使用 ADAL 的 AquireToken(resource, clientCredentials) 重载。

完成后,您的应用应该可以向 Graph 发出请求了。

无论您想坚持使用 A) 还是切换到 B),要仔细检查设置是否正确,您可以:

  1. 检查您从 Graph 返回的令牌(您与 Bearer 一起附加到请求的令牌)并确认它具有包含您需要的角色的角色条目,即 Calendars.Read

注意:以下步骤 2.a 和 2.b 要求您拥有一个测试租户的管理员权限,您将同意该应用程序。

2.a 使用 GraphExplorer (https://graphexplorer2.azurewebsites.net/) 并通过查询

确认已正确设置许可
beta/servicePrincipals?$filter=displayName eq '[YourApplicationName]'

如果什么都没有显示,则表示没有人同意该申请。

2.b(仅适用于具有委托范围的授权代码流)使用 GraphExplorer 并通过查询

确认任一委托已被正确授权
beta/oauth2permissiongrants?$filter=clientId eq '[IdFrom ServicePrincipal in 2.a]' 

并确保您得到有关特定用户或 "AllPrincipals" 的结果。


有关应用与委托范围的更多信息,请点击此处:http://graph.microsoft.io/en-us/docs/authorization/permission_scopes

有关应用流程的更多信息,请点击此处:https://graph.microsoft.io/en-us/docs/authorization/app_only