代表用户获取访问权限
若要调用 Microsoft Graph,应用必须从Microsoft 标识平台获取访问令牌。 此访问令牌包括有关应用是有权代表已登录用户访问Microsoft Graph 还是使用自己的标识访问的信息。 本文提供有关应用如何 代表用户访问 Microsoft Graph(也称为 委托访问)的指导。
本文详细介绍了应用使用名为 OAuth 2.0 授权代码授予流的常用流代表用户获取访问权限所涉及的原始 HTTP 请求。 或者,可以避免编写原始 HTTP 请求,并使用Microsoft构建或支持的身份验证库来处理其中许多详细信息,并帮助你获取访问令牌和调用 Microsoft Graph。 有关详细信息,请参阅 使用 Microsoft 身份验证库 (MSAL) 。
在本文中,你将完成使用 OAuth 2.0 授权代码授予流中的以下步骤:
- 请求授权。
- 请求访问令牌。
- 使用访问令牌调用 Microsoft Graph。
- [可选]使用刷新令牌续订过期的访问令牌。
先决条件
在继续执行本文中的步骤之前:
- 了解Microsoft 标识平台中的身份验证和授权概念。 有关详细信息,请参阅 身份验证和授权基础知识。
- 向 Microsoft Entra ID 注册应用。 有关详细信息,请参阅使用 Microsoft 标识平台注册应用程序。 保存应用注册中的以下值:
- 应用程序 ID (Microsoft Entra 管理中心) 上称为“对象 ID”。
- 客户端密码 (应用程序密码) 、证书或联合标识凭据。 本机、移动和单页应用程序等公共客户端不需要此属性。
- 应用的重定向 URI,用于接收来自Microsoft Entra ID的令牌响应。
步骤 1:请求授权
授权代码流中的第一步是让用户授权应用代表他们执行操作。
在流中,应用将用户重定向到Microsoft 标识平台/authorize
终结点。 通过此终结点,Microsoft Entra ID用户登录并请求其同意应用请求的权限。 获得同意后,Microsoft Entra ID向应用返回授权代码。 然后,应用可以在 Microsoft 标识平台 /token
终结点兑换此代码以获取访问令牌。
授权请求
以下示例显示了对 /authorize
终结点的请求。
在请求 URL 中,调用终结点, /authorize
并将所需属性和建议属性指定为查询参数。
在以下示例中,应用请求 User.Read 和 Mail.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} 值可用于控制登录应用程序的用户。 允许的值是:common organizations consumers 有关详细信息,请参阅 协议基础知识。 |
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.Read 和 Mail.Read)和 OIDC 范围(例如 offline_access ),这表示应用需要刷新令牌才能长期访问资源。 |
response_mode | 建议 | 指定用于将生成的令牌发送回应用的方法。 可以是 query 或 form_post 。 |
状态 | 建议 | 请求中包含的一个值,该值也会在令牌响应中返回。 它可以是所需的任何内容的字符串。 随机生成的唯一值通常用于 防止跨站点请求伪造攻击。 此属性还用于在身份验证请求发生前对应用中有关用户状态的信息进行编码,例如用户所访问的页面或视图。 |
用户同意体验
应用发送授权请求后,系统会要求用户输入其凭据以使用Microsoft进行身份验证。 Microsoft 标识平台 v2.0 终结点可确保用户已同意查询参数中scope
指示的权限。 如果用户或管理员未同意任何权限,系统会要求他们同意所需的权限。 有关Microsoft Entra同意体验的详细信息,请参阅应用程序同意体验和权限和同意简介。
下面是为 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,但应被视为不透明的值,无需检查即可通过该值。 |
步骤 2:请求访问令牌
应用使用在上一步中收到的授权 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} 值可用于控制登录应用程序的用户。 允许的值是:common organizations consumers 有关详细信息,请参阅 协议基础知识。 |
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 令牌参考。 |
步骤 3:使用访问令牌调用 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"
}
步骤 4:使用刷新令牌续订过期的访问令牌
访问令牌生存期较短,应用必须在过期后刷新这些令牌才能继续访问资源。 应用通过向终结点提交另一个 POST
请求 /token
来执行此操作,这次:
-
refresh_token
在请求正文中提供 而不是代码 - 指定
refresh_token
为 grant_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} 值可用于控制登录应用程序的用户。 允许的值是:common organizations consumers 有关详细信息,请参阅 协议基础知识。 |
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 教程。