OAuth 2.0 授权代码授予类型或身份验证代码流使客户端应用程序能够获得对受保护资源(如 Web API)的授权访问。 身份验证代码流需要支持从授权服务器(Microsoft 身份平台)重定向回到应用程序的用户代理。 例如,由用户操作的 Web 浏览器、桌面或移动应用程序,用于登录你的应用并访问用户的数据。
本文介绍了仅在手动制作和发出原始 HTTP 请求来执行流(我们不建议这样做)时才需要的低级协议详细信息。 请改为使用 Microsoft 构建和支持的身份验证库来获取安全令牌并在应用中调用受保护的 Web API。
支持身份验证代码流的应用程序
在这些类型的应用中使用与代码交换的证明密钥 (PKCE) 和 OpenID Connect (OIDC) 配对的身份验证代码流来获取访问令牌和 ID 令牌:
更新重定向 URI:使用 Microsoft Entra 管理中心中的应用程序清单编辑器将重定向 URI 的 type 设置为 spa。
spa 重定向类型与隐式流向后兼容。 当前使用隐式流来获取令牌的应用可以移动到 spa 重定向 URI 类型,而不会出现问题,并会继续使用隐式流。 尽管有这种向后兼容性,还是建议将身份验证代码流与 PKCE for SPA 配合使用。
如果你尝试使用授权代码流而不为重定向 URI 设置 CORS,将在控制台中看到以下错误:
HTTP
access to XMLHttpRequest at 'https://login.microsoftonline.com/common/v2.0/oauth2/token' from origin 'yourApp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&state=12345
&code_challenge=YTFjNjI1OWYzMzA3MTI4ZDY2Njg5M2RkNmVjNDE5YmEyZGRhOGYyM2IzNjdmZWFhMTQ1ODg3NDcxY2Nl
&code_challenge_method=S256
使用 fragment 作为响应模式会导致从重定向读取代码的 Web 应用出现问题。 浏览器不会将片段传递给 Web 服务器。 在这些情况下,应用应该使用 form_post 响应模式,以确保将所有数据发送到服务器。
成功的响应
此示例演示使用 response_mode=fragment 的成功响应:
HTTP
GET https://login.microsoftonline.com/common/oauth2/nativeclient#
code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...
&id_token=eYj...
&state=12345
// 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=11112222-bbbb-3333-cccc-4444dddd5555
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&client_secret=sampleCredentia1s // NOTE: Only required for web apps. This secret needs to be URL-Encoded.
在应用注册门户中为应用创建的应用程序机密。 请不要在本机应用或单页应用中使用应用程序机密,因为 client_secret 无法可靠地存储在设备或网页上。 可将 client_secret 安全地存储在服务器端的 Web 应用和 Web API 需要应用程序机密。 与此处讨论的所有参数一样,客户端机密在发送之前必须进行 URL 编码。 此步骤由 SDK 完成。 有关 URI 编码的详细信息,请参阅 URI 常规语法规范。 还支持根据 RFC 6749 在授权标头中提供凭据的基本身份验证模式。
使用证书凭据请求访问令牌
HTTP
// Line breaks for legibility only
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/mail.read is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
"error_codes": [
70011
],
"timestamp": "2016-01-09 02:02:12Z",
"trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
"correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
参数
说明
error
一个错误代码字符串,可用于对错误类型进行分类并对错误做出反应。
error_description
帮助开发人员识别身份验证错误原因的特定错误消息。
error_codes
可帮助诊断的 STS 特定错误代码列表。
timestamp
发生错误的时间。
trace_id
可帮助诊断的请求唯一标识符。
correlation_id
可帮助跨组件诊断的请求唯一标识符。
令牌终结点错误的错误代码
错误代码
说明
客户端操作
invalid_request
协议错误,例如,缺少必需的参数。
修复请求或应用注册,然后重新提交请求。
invalid_grant
授权代码或 PKCE 代码验证程序无效或已过期。
尝试向 /authorize 终结点发送新请求,并验证 code_verifier 参数是否正确。
unauthorized_client
经过身份验证的客户端无权使用此权限授予类型。
客户端应用程序未注册到 Microsoft Entra ID 中或者未添加到用户的 Microsoft Entra 租户时,通常会出现这种错误。 应用程序可以提示用户,并说明如何安装应用程序并将其添加到 Microsoft Entra ID。
invalid_client
客户端身份验证失败。
客户端凭据无效。 若要修复,应用程序管理员应更新凭据。
unsupported_grant_type
授权服务器不支持权限授予类型。
更改请求中的授权类型。 这种类型的错误应该只在开发过程中发生,并且应该在初始测试过程中检测到。
invalid_resource
目标资源无效,原因是它不存在,Microsoft Entra ID 找不到它,或者其未正确配置。
此代码指示资源(如果存在)尚未在租户中配置。 应用程序可以提示用户,并说明如何安装应用程序并将其添加到 Microsoft Entra ID。
// 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=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&grant_type=refresh_token
&client_secret=sampleCredentia1s // NOTE: Only required for web apps. This secret needs to be URL-Encoded
范围的空格分隔列表。 在此阶段中请求的范围必须相当于或为原始 authorization_code 请求分支中所请求的范围子集。 如果此请求中指定的范围涵盖多个资源服务器,Microsoft 标识平台将返回第一个范围中指定的资源的令牌。 有关详细信息,请参阅 Microsoft 标识平台中的权限和同意。
refresh_token
必需
在流的第二个分支中获取的 refresh_token。
client_secret
必填(对于 Web 应用)
在应用注册门户中为应用创建的应用程序机密。 不应在本机应用中使用该机密,因为无法在设备上可靠存储 client_secret。 可将 client_secret 安全地存储在服务器端的 Web 应用和 Web API 需要应用程序机密。 此机密需要进行 URL 编码。 有关详细信息,请参阅 URI 一般语法规范。
未签名的 JSON Web 令牌。 应用可以解码此令牌的段,以请求有关登录用户的信息。 应用可以缓存并显示这些值,但不应依赖它们来获取任何授权或安全边界。 有关 id_token 的详细信息,请参阅 Microsoft 标识平台 ID 令牌。 注意: 仅当已请求 openid 作用域时提供。
警告
请勿尝试在代码中验证或读取你未拥有的任何 API 的令牌,包括此示例中的令牌。 Microsoft 服务的令牌可以使用将不会作为 JWT 进行验证的特殊格式,还可能会针对使用者(Microsoft 帐户)用户进行加密。 虽然可以通过读取令牌的操作进行调试和学习,但请不要在代码中依赖此操作,也不要假定不是你控制的 API 的令牌的相关具体信息。
错误响应
JSON
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/mail.read is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
"error_codes": [
70011
],
"timestamp": "2016-01-09 02:02:12Z",
"trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
"correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}