检索访问令牌时出现“一个或多个范围彼此不兼容”错误

Yor*_*ova 2 azure-active-directory outlook-restapi microsoft-graph-api

我有一个通过 Azure AD REST API v.2 与 Outlook、日历集成的应用程序。我尝试使用增量和动态范围来“升级”用户的令牌,以便应用程序也可以访问 OneDrive(这样用户就可以直接在云中上传电子邮件附件)。授权代码检索重定向进展顺利,用户在登录后会被要求提供附加范围(files.readwrite)。但是,在步骤 2 中,当我尝试获取访问令牌时,出现以下错误:

System.Exception: Acquire token by authorization code returned BadRequest: 

{
  "error": "invalid_scope",
  "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. One or more scopes in 'https://outlook.office.com/mail.readwrite https://outlook.office.com/mail.send https://outlook.office.com/contacts.readwrite https://outlook.office.com/calendars.readwrite https://outlook.office.com/people.read files.readwrite' are not compatible with each other.\\r\\nTrace ID: b02fa0bf-6e86-4156-81e8-294dbc851500\\r\\nCorrelation ID: 3697bd18-554c-47e6-81cc-de3c47780fc9\\r\\nTimestamp: 2018-02-01 15:26:10Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2018-02-01 15:26:10Z",
  "trace_id": "b02fa0bf-6e86-4156-81e8-294dbc851500",
  "correlation_id": "3697bd18-554c-47e6-81cc-de3c47780fc9"
}
Run Code Online (Sandbox Code Playgroud)

或者这个错误:

System.Exception: Acquire token by authorization code returned BadRequest: 
{
  "error": "invalid_request",
  "error_description": "AADSTS700022: The provided value for the input parameter scope is not valid because it contains more than one resource. The scope https://outlook.office.com/mail.readwrite https://outlook.office.com/mail.send https://outlook.office.com/contacts.readwrite https://outlook.office.com/calendars.readwrite https://outlook.office.com/people.read files.readwrite is not valid.\\r\\nTrace ID: 9781d206-11b3-46c8-b972-8c4e77641c00\\r\\nCorrelation ID: 7e63af89-6e95-45f4-abaa-8f32051fb9ef\\r\\nTimestamp: 2018-02-01 15:36:32Z",
  "error_codes": [
    700022
  ],
  "timestamp": "2018-02-01 15:36:32Z",
  "trace_id": "9781d206-11b3-46c8-b972-8c4e77641c00",
  "correlation_id": "7e63af89-6e95-45f4-abaa-8f32051fb9ef"
}
Run Code Online (Sandbox Code Playgroud)

我假设我不能对 Outlook 和 OneDrive 访问使用相同的令牌,因为它们是“不同的资源”,一个是 Office 365 的一部分,另一个是 Microsoft graph 的一部分,但是,我很难找到哪些资源的完整列表与此处兼容(https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-scopes)。

我的问题是,这是否意味着我需要为 OneDrive 和 Outlook 维护 2 个不同的令牌(我的应用程序使用离线范围来刷新令牌)?

另外,个人帐户的 OneDrive 和企业帐户的 OneDrive 之间是否有区别(我认为与 Sharepoint 相同)?使用 Outlook 时,我可以对 Outlook.com 和 Office365 电子邮件使用相同的代码,但我不确定处理文件时是否是这种情况。

使用 Google API,只需将 Google Drive(或任何其他 API)范围添加到 Gmail 访问范围就非常简单,但我想 Microsoft API 的情况并非如此。

谢谢

Jas*_*ton 7

是的,您将需要两个令牌。正如 juunas 在评论中所说,问题在于受众,或者说是audtoken 中的参数。您要求适用于两个不同受众的范围:https://outlook.office.comhttps://graph.microsoft.com

好消息是,这两个 API 确实具有重叠的范围,并且 Azure AD 将允许您使用为 Graph 颁发的刷新令牌来获取 Outlook API 的令牌。所以这就是我的建议(假设您正在执行授权代码流程

  1. 使用 Graph 范围执行授权请求:

    mail.readwrite 
    mail.send 
    contacts.readwrite 
    calendars.readwrite 
    people.read 
    files.readwrite
    
    Run Code Online (Sandbox Code Playgroud)
  2. grant_type=authorization_code使用相同的图形范围执行令牌请求。这将获取您的图形令牌+刷新令牌。

  3. 使用上一步中的刷新令牌执行令牌请求grant_type=refresh_token,但这次仅使用 Outlook 适用的范围,符合https://outlook.office.com. 这将获取您的 Outlook 令牌。

    https://outlook.office.com/mail.readwrite 
    https://outlook.office.com/mail.send 
    https://outlook.office.com/contacts.readwrite 
    https://outlook.office.com/calendars.readwrite 
    https://outlook.office.com/people.read 
    
    Run Code Online (Sandbox Code Playgroud)