代表用户获取访问权限

若要调用 Microsoft Graph,应用必须从Microsoft 标识平台获取访问令牌。 此访问令牌包括有关应用是有权代表已登录用户访问 Microsoft Graph 还是使用其自己的标识的信息。 本文提供有关应用如何 代表用户访问 Microsoft Graph(也称为 委托访问)的指南。

本文详细介绍了应用使用名为 OAuth 2.0 授权代码授予流的常用流代表用户获取访问权限所涉及的原始 HTTP 请求。 或者,可以避免编写原始 HTTP 请求,并使用 Microsoft 构建或支持的身份验证库来处理其中许多详细信息,并帮助你获取访问令牌和调用 Microsoft Graph。 有关详细信息,请参阅 使用 Microsoft 身份验证库 (MSAL)

先决条件

在继续执行本文中的步骤之前:

  1. 了解Microsoft 标识平台中的身份验证和授权概念。 有关详细信息,请参阅 身份验证和授权基础知识
  2. 向 Microsoft Entra ID 注册应用。 有关详细信息,请参阅使用 Microsoft 标识平台注册应用程序

身份验证和授权步骤

若要使应用使用授权代码流获取对 Microsoft Graph 的授权和访问权限,必须执行以下五个步骤:

  1. 向 Microsoft Entra ID 注册应用。
  2. 请求授权。
  3. 请求访问令牌。
  4. 使用访问令牌调用 Microsoft Graph。
  5. [可选]使用刷新令牌续订过期的访问令牌。

1.注册应用

应用必须正确注册,然后应用才能调用 Microsoft 标识平台 终结点或 Microsoft Graph。 按照步骤在Microsoft Entra 管理中心注册应用

在应用注册中,保存以下值:

  • 应用程序 ID (应用注册门户分配的Microsoft Entra 管理中心) 上称为“对象 ID”。
  • 重定向 URI (或回复 URL) ,以便应用接收来自Microsoft Entra ID的响应。
  • 客户端密码 (应用程序密码) 、证书或联合标识凭据。 本机、移动和单页应用程序等公共客户端不需要此属性。

2.请求授权

授权代码流中的第一步是让用户授权应用代表他们执行操作。

在流中,应用将用户重定向到Microsoft 标识平台/authorize终结点。 通过此终结点,Microsoft Entra ID用户登录并请求其同意应用请求的权限。 获得同意后,Microsoft Entra ID将向应用返回授权代码。 然后,应用可以在 Microsoft 标识平台 /token 终结点兑换此代码以获取访问令牌。

授权请求

以下示例显示了对 /authorize 终结点的请求。

在请求 URL 中,调用终结点, /authorize 并将所需属性和建议属性指定为查询参数。

在以下示例中,应用请求 User.ReadMail.Read Microsoft Graph 权限,这允许应用分别读取已登录用户的个人资料和邮件。 offline_access权限是请求的标准 OIDC 范围,以便应用可以获取刷新令牌。 当当前令牌过期时,应用可以使用刷新令牌来获取新的访问令牌。

// Line breaks for legibility only

GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=11111111-1111-1111-1111-111111111111
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=offline_access%20user.read%20mail.read
&state=12345  HTTP/1.1
参数
参数 必需 说明
租户 必需 请求路径中的 {tenant} 值可用于控制登录应用程序的用户。 允许的值是:
  • Microsoft 帐户和工作或学校帐户的 common
  • 仅适用于工作或学校帐户的 organizations
  • 仅适用于 Microsoft 帐户的 consumers
  • 租户标识符,如租户 ID 或域名。
    有关详细信息,请参阅 协议基础知识
  • client_id 必需 应用程序 (客户端) 注册门户 分配应用的 ID。 在 Microsoft Graph 应用程序和服务主体对象中也称为 appId
    response_type 必需 必须包含 code OAuth 2.0 授权代码流。
    redirect_uri 建议 应用的重定向 URI,身份验证响应将发送到应用并由应用接收。 它必须与在应用注册门户中注册的重定向 URI 之一完全匹配,除非它必须经过 URL 编码。 对于本机应用和移动应用,应使用默认值 https://login.microsoftonline.com/common/oauth2/nativeclient
    范围 必需 由空格分隔的希望用户同意的 Microsoft Graph 权限列表。 这些权限可以包括资源权限(例如 User.ReadMail.Read)和 OIDC 范围(例如 offline_access),这表示应用需要刷新令牌才能长期访问资源。
    response_mode 建议 指定用于将生成的令牌发送回应用的方法。 可以是 queryform_post
    状态 建议 请求中包含的一个值,该值也会在令牌响应中返回。 它可以是所需的任何内容的字符串。 随机生成的唯一值通常用于 防止跨站点请求伪造攻击。 此属性还用于在身份验证请求发生前对应用中有关用户状态的信息进行编码,例如用户所访问的页面或视图。

    应用发送授权请求后,系统会要求用户输入其凭据以向 Microsoft 进行身份验证。 Microsoft 标识平台 v2.0 终结点可确保用户已同意查询参数中scope指示的权限。 如果用户或管理员未同意任何权限,系统会要求他们同意所需的权限。 有关Microsoft Entra同意体验的详细信息,请参阅应用程序同意体验权限和同意简介

    下面是为 Microsoft 帐户用户呈现的同意对话框屏幕截图。

    Microsoft 帐户的同意对话框。

    授权响应

    如果用户同意应用请求的权限,则响应将包含 参数中的 code 授权代码。 下面是对上一个请求的成功响应的示例。 response_mode由于请求中的 参数设置为 query,因此响应在重定向 URL 的查询字符串中返回。

    HTTP/1.1 200 OK
    
    https://localhost/myapp/?code=M0ab92efe-b6fd-df08-87dc-2c6500a7f84d&state=12345&session_state=fe1540c3-a69a-469a-9fa3-8a2470936421#
    
    查询参数
    参数 说明
    code 应用请求的授权代码。 应用使用授权代码请求目标资源的访问令牌。 授权代码生存期较短,通常在大约 10 分钟后过期。
    state 如果请求中包含状态参数,响应中应显示相同的值。 应用应验证请求和响应中的状态值是否相同。 此检查有助于检测跨站点请求伪造 (CSRF) 针对客户端的攻击。
    session_state 标识当前用户会话的唯一值。 此值是一个 GUID,但应被视为不透明的值,无需检查即可通过该值。

    3.请求访问令牌

    应用使用在上一步中收到的授权 code ,通过向终结点发送 POST 请求来请求 /token 访问令牌。

    令牌请求

    // Line breaks for legibility only
    
    POST /{tenant}/oauth2/v2.0/token HTTP/1.1
    Host: https://login.microsoftonline.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=11111111-1111-1111-1111-111111111111
    &scope=user.read%20mail.read
    &code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
    &redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
    &grant_type=authorization_code
    &client_secret=HF8Q~Krjqh4r...    // NOTE: Only required for web apps
    
    参数
    参数 必需 说明
    租户 必需 请求路径中的 {tenant} 值可用于控制登录应用程序的用户。 允许的值是:
  • Microsoft 帐户和工作或学校帐户的 common
  • 仅适用于工作或学校帐户的 organizations
  • 仅适用于 Microsoft 帐户的 consumers
  • 租户标识符,如租户 ID 或域名。
    有关详细信息,请参阅 协议基础知识
  • client_id 必需 应用程序 (客户端) 注册门户 分配应用的 ID。 在 Microsoft Graph 应用程序和服务主体对象中也称为 appId
    grant_type 必需 对于授权代码流必须为 authorization_code
    范围 必需 以空格分隔的范围列表。 你的应用在此回合中请求的范围必须等效于或在步骤 2 的授权回合中请求的范围子集。 如果此请求中指定的范围跨越多个资源服务器,则 v2.0 终结点将返回在第一个作用域中指定的资源的令牌。
    code 必需 在步骤 2 的授权过程中获取的授权 代码
    redirect_uri 必需 在步骤 2 中用于获取授权 代码 的相同重定向 URI 值。
    client_secret Web 应用需要 在应用注册门户中为应用创建的客户端密码。 它不应在本机应用中使用,因为客户端机密无法可靠地存储在设备上。 Web 应用和 Web API 需要它,它们能够安全地将client_secret存储在服务器端。

    令牌响应

    访问令牌包含在 参数中 scope 适合访问令牌的权限列表。 响应类似于以下示例。

    HTTP/1.1 200 OK
    Content-type: application/json
    
    {
        "token_type": "Bearer",
        "scope": "Mail.Read User.Read",
        "expires_in": 3736,
        "ext_expires_in": 3736,
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
        "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4..."
    }
    
    响应正文属性
    参数 说明
    token_type 指示令牌类型值。 Microsoft Entra ID支持的唯一类型是 Bearer
    范围 访问令牌有效的 Microsoft Graph 权限的空格分隔列表。
    expires_in 访问令牌的有效期是多久(以秒为单位)。
    ext_expires_in 指示访问令牌 (的延长生存期(以秒为单位) ,用于在令牌颁发服务未响应时支持复原能力)。
    access_token 请求的访问令牌。 应用可以使用此令牌来调用 Microsoft Graph。
    refresh_token OAuth 2.0 刷新令牌。 在当前访问令牌过期后,应用可以使用此令牌获取其他访问令牌。 刷新令牌有效期较长,可用于长时间保留对资源的访问权限。 仅当 offline_access 作为参数包含 scope 时,才会返回刷新令牌。 有关详细信息,请参阅 v2.0 令牌参考

    4. 使用访问令牌调用 Microsoft Graph

    拥有访问令牌后,应用会使用它调用 Microsoft Graph,方法是将访问令牌作为 持有者 令牌附加到 HTTP 请求中的 Authorization 标头。 以下请求获取已登录用户的配置文件。

    请求

    GET https://graph.microsoft.com/v1.0/me  HTTP/1.1
    Authorization: Bearer eyJ0eXAiO ... 0X2tnSQLEANnSPHY0gKcgw
    Host: graph.microsoft.com
    

    响应

    成功的响应类似于以下 () 删除了某些响应标头。

    HTTP/1.1 200 OK
    Content-Type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8
    request-id: f45d08c0-6901-473a-90f5-7867287de97f
    client-request-id: f45d08c0-6901-473a-90f5-7867287de97f
    OData-Version: 4.0
    Duration: 727.0022
    Date: Thu, 20 Apr 2017 05:21:18 GMT
    Content-Length: 407
    
    {
        "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
        "businessPhones": [
            "425-555-0100"
        ],
        "displayName": "MOD Administrator",
        "givenName": "MOD",
        "jobTitle": null,
        "mail": "admin@contoso.com",
        "mobilePhone": "425-555-0101",
        "officeLocation": null,
        "preferredLanguage": "en-US",
        "surname": "Administrator",
        "userPrincipalName": "admin@contoso.com",
        "id": "10a08e2e-3ea2-4ce0-80cb-d5fdd4b05ea6"
    }
    

    5. 使用刷新令牌续订过期的访问令牌

    访问令牌生存期较短,应用必须在过期后刷新这些令牌才能继续访问资源。 应用通过向终结点提交另一个 POST 请求 /token 来执行此操作,这次:

    • refresh_token在请求正文中提供 而不是代码
    • 指定 refresh_tokengrant_type,而不是 authorization_code

    请求

    // Line breaks for legibility only
    
    POST /{tenant}/oauth2/v2.0/token HTTP/1.1
    Host: https://login.microsoftonline.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=11111111-1111-1111-1111-111111111111
    &scope=user.read%20mail.read
    &refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
    &grant_type=refresh_token
    &client_secret=jXoM3iz...      // NOTE: Only required for web apps
    
    参数
    参数 必需 说明
    租户 必需 请求路径中的 {tenant} 值可用于控制登录应用程序的用户。 允许的值是:
  • Microsoft 帐户和工作或学校帐户的 common
  • 仅适用于工作或学校帐户的 organizations
  • 仅适用于 Microsoft 帐户的 consumers
  • 租户标识符,如租户 ID 或域名。
    有关详细信息,请参阅 协议基础知识
  • client_id 必需 应用程序 (客户端) 注册门户 分配应用的 ID。 在 Microsoft Graph 应用程序和服务主体对象中也称为 appId
    grant_type 必需 必须是 refresh_token
    范围 可选 以空格分隔的权限列表 (范围) 。 你的应用请求的权限必须等效于步骤 2 中的原始授权代码请求中请求的权限或权限的子集。
    refresh_token 必需 在步骤 3 中,应用在令牌请求期间获取refresh_token。
    client_secret Web 应用需要 在应用注册门户中为应用创建的客户端密码。 请勿在本机应用中使用该机密,因为client_secrets无法可靠地存储在设备上。 Web 应用和 Web API 需要它,它们能够安全地将client_secret存储在服务器端。

    响应

    成功的令牌响应如下所示。

    HTTP/1.1 200 OK
    Content-type: application/json
    
    {
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
        "token_type": "Bearer",
        "expires_in": 3599,
        "scope": "Mail.Read User.Read",
        "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    }
    
    响应正文参数
    参数 说明
    access_token 请求的访问令牌。 应用可以在调用 Microsoft Graph 时使用此令牌。
    token_type 指示令牌类型值。 Microsoft Entra ID支持的唯一类型是 Bearer
    expires_in 访问令牌的有效期是多久(以秒为单位)。
    范围 access_token 适用的权限(范围)。
    refresh_token 新的 OAuth 2.0 刷新令牌。 将旧的刷新令牌替换为此新获取的刷新令牌,以确保刷新令牌在尽可能长的时间内保持有效。

    使用 Microsoft 身份验证库 (MSAL)

    本文介绍了通常仅在手动创建和发出原始 HTTP 请求以执行授权代码流时所需的低级别协议详细信息。 在生产应用中,使用 Microsoft 生成或支持的身份验证库(例如 Microsoft 身份验证库 (MSAL) )获取安全令牌并调用受保护的 Web API(如 Microsoft Graph)。

    MSAL 和其他受支持的身份验证库通过处理验证、Cookie 处理、令牌缓存和安全连接等详细信息简化了此过程,使你能够专注于应用程序的功能。

    Microsoft 生成并维护了各种代码示例,这些示例演示了Microsoft 标识平台支持的身份验证库的用法。 若要访问这些代码示例,请参阅Microsoft 标识平台代码示例

    • 你可以代表用户从不同类型的应用(例如单页应用、Web 应用和移动应用)调用 Microsoft Graph。 有关详细信息,请参阅 方案和支持的身份验证流
    • 从 Microsoft 生成和维护的代码示例中进行选择,以运行使用支持的身份验证库、登录用户和调用 Microsoft Graph 的自定义应用。 请参阅 Microsoft Graph 教程