Microsoft 标识平台和 OAuth 2.0 授权代码流Microsoft identity platform and OAuth 2.0 authorization code flow

OAuth 2.0 授权代码授予可用于设备上所安装的应用,以访问受保护的资源,例如 Web API。The OAuth 2.0 authorization code grant can be used in apps that are installed on a device to gain access to protected resources, such as web APIs. 使用 OAuth 2.0 的 Microsoft 标识平台实现,可以将登录名及 API 访问添加到移动应用和桌面应用。Using the Microsoft identity platform implementation of OAuth 2.0, you can add sign in and API access to your mobile and desktop apps.

本文介绍如何使用任何语言直接针对应用程序中的协议编程。This article describes how to program directly against the protocol in your application using any language. 如果可能,建议改为使用受支持的 Microsoft 身份验证库 (MSAL) 来获取令牌并调用受保护的 Web APIWhen possible, we recommend you use the supported Microsoft Authentication Libraries (MSAL) instead to acquire tokens and call secured web APIs. 另请参阅使用 MSAL 的示例应用Also take a look at the sample apps that use MSAL.

OAuth 2.0 规范第 4.1 部分描述了 OAuth 2.0 授权代码流。The OAuth 2.0 authorization code flow is described in section 4.1 of the OAuth 2.0 specification. 它用于在大部分的应用类型(包括单页应用Web 应用本机安装的应用)中执行身份验证与授权。It's used to perform authentication and authorization in the majority of app types, including single page apps, web apps, and natively installed apps. 通过此流,应用能安全地获取可用于访问由 Microsoft 标识平台终结点保护的资源的 access_tokens,以及刷新令牌以获取其他 access_tokens 和登录用户的 ID 令牌。The flow enables apps to securely acquire access_tokens that can be used to access resources secured by the Microsoft identity platform endpoint, as well as refresh tokens to get additional access_tokens, and ID tokens for the signed in user.

协议图Protocol diagram

概括而言,应用程序的整个身份验证流看起来有点类似于:At a high level, the entire authentication flow for an application looks a bit like this:

OAuth 授权代码流

单页应用所需的重定向 URI 设置Redirect URI setup required for single-page apps

单页应用程序的授权代码流需要一些其他设置。The authorization code flow for single page applications requires some additional setup. 按照创建单页应用程序的说明将重定向 URI 正确地标记为已为 CORS 启用。Follow the instructions for creating your single-page application to correctly mark your redirect URI as enabled for CORS. 若要更新现有的重定向 URI 以启用 CORS,请打开清单编辑器,然后在 replyUrlsWithType 部分中将重定向 URI 的 type 字段设置为 spaTo update an existing redirect URI to enable CORS, open the manifest editor and set the type field for your redirect URI to spa in the replyUrlsWithType section. 还可以在“身份验证”选项卡的“Web”部分单击重定向 URI,然后使用授权代码流选择要迁移到的 URI。You can also click on the redirect URI in the "Web" section of the Authentication tab, and select the URIs you want to migrate to using the authorization code flow.

spa 重定向类型与隐式流向后兼容。The spa redirect type is backwards compatible with the implicit flow. 当前使用隐式流来获取令牌的应用可以移动到 spa 重定向 URI 类型,而不会出现问题,并会继续使用隐式流。Apps currently using the implicit flow to get tokens can move to the spa redirect URI type without issues and continue using the implicit flow.

如果尝试使用授权代码流并查看此错误:If you attempt to use the authorization code flow and see this error:

access to XMLHttpRequest at 'https://login.partner.microsoftonline.cn/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.

则需要访问应用注册,并更新应用的重定向 URI 以键入 spaThen you need to visit your app registration and update the redirect URI for your app to type spa.

请求授权代码Request an authorization code

授权代码流始于客户端将用户定向到 /authorize 终结点。The authorization code flow begins with the client directing the user to the /authorize endpoint. 在此请求中,客户端向用户请求 openidoffline_accesshttps://microsoftgraph.chinacloudapi.cn/mail.read 权限。In this request, the client requests the openid, offline_access, and https://microsoftgraph.chinacloudapi.cn/mail.read permissions from the user. 某些权限受管理员限制,例如,使用 Directory.ReadWrite.All 将数据写入组织的目录。Some permissions are admin-restricted, for example writing data to an organization's directory by using Directory.ReadWrite.All. 如果应用程序向组织用户请求访问以下权限之一,则用户会收到错误消息,显示他们未经授权,无法同意应用的权限。If your application requests access to one of these permissions from an organizational user, the user receives an error message that says they're not authorized to consent to your app's permissions. 若要请求访问受管理员限制的范围,应该直接向公司管理员请求。To request access to admin-restricted scopes, you should request them directly from a company administrator. 有关详细信息,请参阅管理员限制的权限For more information, read Admin-restricted permissions.

// Line breaks for legibility only

https://login.partner.microsoftonline.cn/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=openid%20offline_access%20https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2Fmail.read
&state=12345
&code_challenge=YTFjNjI1OWYzMzA3MTI4ZDY2Njg5M2RkNmVjNDE5YmEyZGRhOGYyM2IzNjdmZWFhMTQ1ODg3NDcxY2Nl
&code_challenge_method=S256

提示

单击下面的链接以执行此请求!Click the link below to execute this request! 登录之后,浏览器应重定向至地址栏中具有 codehttps://localhost/myapp/After signing in, your browser should be redirected to https://localhost/myapp/ with a code in the address bar. https://login.partner.microsoftonline.cn/common/oauth2/v2.0/authorize...https://login.partner.microsoftonline.cn/common/oauth2/v2.0/authorize...

参数Parameter 必需/可选Required/optional 说明Description
tenant 必需required 请求路径中的 {tenant} 值可用于控制哪些用户可以登录应用程序。The {tenant} value in the path of the request can be used to control who can sign into the application. 可以使用的值包括 commonorganizationsconsumers 和租户标识符。The allowed values are common, organizations, consumers, and tenant identifiers. 有关详细信息,请参阅协议基础知识For more detail, see protocol basics.
client_id 必填required Azure 门户 - 应用注册体验分配给应用的应用程序(客户端)IDThe Application (client) ID that the Azure portal - App registrations experience assigned to your app.
response_type 必填required 必须包括授权代码流的 codeMust include code for the authorization code flow.
redirect_uri 必需required 应用的 redirect_uri,应用可向其发送及从其接收身份验证响应。The redirect_uri of your app, where authentication responses can be sent and received by your app. 它必须完全符合在门户中注册的其中一个 redirect_uris,否则必须是编码的 url。It must exactly match one of the redirect_uris you registered in the portal, except it must be url encoded. 对于本机和移动应用,应使用默认值 https://login.partner.microsoftonline.cn/common/oauth2/nativeclientFor native & mobile apps, you should use the default value of https://login.partner.microsoftonline.cn/common/oauth2/nativeclient.
scope 必需required 希望用户同意的范围的空格分隔列表。A space-separated list of scopes that you want the user to consent to. 对于请求的 /authorize 段,这可以涵盖多个资源,从而允许应用获得你要调用的多个 Web API 的同意。For the /authorize leg of the request, this can cover multiple resources, allowing your app to get consent for multiple web APIs you want to call.
response_mode 建议recommended 指定将生成的令牌送回到应用程序时应该使用的方法。Specifies the method that should be used to send the resulting token back to your app. 可以是以下值之一:Can be one of the following:

- query
- fragment
- form_post

query 在重定向 URI 上提供代码作为查询字符串参数。query provides the code as a query string parameter on your redirect URI. 如果要使用隐式流请求 ID 令牌,则不能使用 OpenID 规范中指定的 query。如果只是请求代码,则可以使用 queryfragmentform_postIf you're requesting an ID token using the implicit flow, you can't use query as specified in the OpenID spec. If you're requesting just the code, you can use query, fragment, or form_post. form_post 对重定向 URI 执行包含代码的 POST。form_post executes a POST containing the code to your redirect URI. 有关详细信息,请参阅 OpenID Connect 协议For more info, see OpenID Connect protocol.
state 建议recommended 同样随令牌响应返回的请求中所包含的值。A value included in the request that will also be returned in the token response. 可以是想要的任何内容的字符串。It can be a string of any content that you wish. 随机生成的唯一值通常用于 防止跨站点请求伪造攻击A randomly generated unique value is typically used for preventing cross-site request forgery attacks. 在发出身份验证请求出现之前,此值对有关用户在应用中的状态的信息(例如前面所在的页面或视图)进行编码。The value can also encode information about the user's state in the app before the authentication request occurred, such as the page or view they were on.
prompt 可选optional 表示需要的用户交互类型。Indicates the type of user interaction that is required. 目前仅有的有效值为 loginnoneconsentThe only valid values at this time are login, none, and consent.

- prompt=login 将强制用户在该请求上输入其凭据,从而使单一登录无效。- prompt=login will force the user to enter their credentials on that request, negating single-sign on.
- prompt=none 则相反 - 它确保不对用户显示任何交互式提示。- prompt=none is the opposite - it will ensure that the user isn't presented with any interactive prompt whatsoever. 如果请求无法通过单一登录静默完成,则 Microsoft 标识平台终结点将返回 interaction_required 错误。If the request can't be completed silently via single-sign on, the Microsoft identity platform endpoint will return an interaction_required error.
- prompt=consent 在用户登录后将触发 OAuth 同意对话框,要求用户向应用授予权限。- prompt=consent will trigger the OAuth consent dialog after the user signs in, asking the user to grant permissions to the app.
- prompt=select_account 将中断单一登录,提供帐户选择体验(列出所有帐户(会话中的帐户或任何记住的帐户),或提供用于选择使用其他帐户的选项)。- prompt=select_account will interrupt single sign-on providing account selection experience listing all the accounts either in session or any remembered account or an option to choose to use a different account altogether.
login_hint 可选optional 如果事先知道用户名,可用于预先填充用户登录页的用户名/电子邮件地址字段。Can be used to pre-fill the username/email address field of the sign-in page for the user, if you know their username ahead of time. 通常,应用会在重新身份验证期间使用此参数,并且已经使用 preferred_username 声明从前次登录提取用户名。Often apps will use this parameter during re-authentication, having already extracted the username from a previous sign-in using the preferred_username claim.
domain_hint 可选optional 如果已包含在内,它将跳过用户在登录页面上经历的基于电子邮件的发现过程,从而实现更加流畅的用户体验,例如,将其发送给联合标识提供者。If included, it will skip the email-based discovery process that user goes through on the sign-in page, leading to a slightly more streamlined user experience - for example, sending them to their federated identity provider. 通常,应用将在重新身份验证期间使用此参数,方法是从上次登录提取 tidOften apps will use this parameter during re-authentication, by extracting the tid from a previous sign-in. 如果 tid 声明值是 9188040d-6c67-4c5b-b112-36a304b66dad,应该使用 domain_hint=consumersIf the tid claim value is 9188040d-6c67-4c5b-b112-36a304b66dad, you should use domain_hint=consumers. 否则使用 domain_hint=organizationsOtherwise, use domain_hint=organizations.
code_challenge 建议/必需recommended / required 用于通过 Proof Key for Code Exchange (PKCE) 保护授权代码授权。Used to secure authorization code grants via Proof Key for Code Exchange (PKCE). 如果包含 code_challenge_method,则需要。Required if code_challenge_method is included. 有关详细信息,请参阅 PKCE RFCFor more information, see the PKCE RFC. 现在建议用于所有应用程序类型 - 本机应用、SPA 和机密客户端(如 Web 应用)。This is now recommended for all application types - native apps, SPAs, and confidential clients like web apps.
code_challenge_method 建议/必需recommended / required 用于为 code_challenge 参数编码 code_verifier 的方法。The method used to encode the code_verifier for the code_challenge parameter. 它应该为 S256,但是如果客户端出于某种原因不能支持 SHA256,则该规范允许使用 plainThis SHOULD be S256, but the spec allows the use of plain if for some reason the client cannot support SHA256.

如果已排除在外,且包含了 code_challenge,则假定 code_challenge 为纯文本。If excluded, code_challenge is assumed to be plaintext if code_challenge is included. Microsoft 标识平台支持 plainS256Microsoft identity platform supports both plain and S256. 有关详细信息,请参阅 PKCE RFCFor more information, see the PKCE RFC. 这是使用授权代码流的单页应用所必需的。This is required for single page apps using the authorization code flow.

此时,将请求用户输入凭据并完成身份验证。At this point, the user will be asked to enter their credentials and complete the authentication. Microsoft 标识平台终结点还会确保用户已许可 scope 查询参数中指定的权限。The Microsoft identity platform endpoint will also ensure that the user has consented to the permissions indicated in the scope query parameter. 如果用户未曾同意这些权限的任何一项,则请求用户同意请求的权限。If the user has not consented to any of those permissions, it will ask the user to consent to the required permissions. 此处提供了权限、许可与多租户应用的详细信息。Details of permissions, consent, and multi-tenant apps are provided here.

用户经过身份验证并授予许可后,Microsoft 标识平台终结点将使用 response_mode 参数中指定的方法,将响应返回到位于所指示的 redirect_uri 的应用。Once the user authenticates and grants consent, the Microsoft identity platform endpoint will return a response to your app at the indicated redirect_uri, using the method specified in the response_mode parameter.

成功的响应Successful response

使用 response_mode=query 的成功响应如下所示:A successful response using response_mode=query looks like:

GET https://login.partner.microsoftonline.cn/common/oauth2/nativeclient?
code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...
&state=12345
参数Parameter 说明Description
code 应用请求的 authorization_code。The authorization_code that the app requested. 应用可以使用授权代码请求目标资源的访问令牌。The app can use the authorization code to request an access token for the target resource. Authorization_codes 的生存期较短,通常在约 10 分钟后即过期。Authorization_codes are short lived, typically they expire after about 10 minutes.
state 如果请求中包含 state 参数,响应中就应该出现相同的值。If a state parameter is included in the request, the same value should appear in the response. 应用应该验证请求和响应中的 state 值是否完全相同。The app should verify that the state values in the request and response are identical.

还会收到访问令牌和 ID 令牌,前提是请求一个令牌并在应用程序注册中启用了隐式授权。You can also receive an access token and ID token if you request one and have the implicit grant enabled in your application registration. 这有时称为“混合流”,并由 ASP.NET 等框架使用。This is sometimes referred to as the "hybrid flow", and is used by frameworks like ASP.NET.

错误响应Error response

错误响应可能也发送到 redirect_uri ,让应用可以适当地处理:Error responses may also be sent to the redirect_uri so the app can handle them appropriately:

GET https://login.partner.microsoftonline.cn/common/oauth2/nativeclient?
error=access_denied
&error_description=the+user+canceled+the+authentication
参数Parameter 说明Description
error 可用于分类发生的错误类型与响应错误的错误码字符串。An error code string that can be used to classify types of errors that occur, and can be used to react to errors.
error_description 帮助开发人员识别身份验证错误根本原因的特定错误消息。A specific error message that can help a developer identify the root cause of an authentication error.

授权终结点错误的错误代码Error codes for authorization endpoint errors

下表描述了可在错误响应的 error 参数中返回的各个错误代码。The following table describes the various error codes that can be returned in the error parameter of the error response.

错误代码Error Code 说明Description 客户端操作Client Action
invalid_request 协议错误,例如,缺少必需的参数。Protocol error, such as a missing required parameter. 修复并重新提交请求。Fix and resubmit the request. 这通常是在初始测试期间捕获的开发错误。This is a development error typically caught during initial testing.
unauthorized_client 不允许客户端应用程序请求授权代码。The client application isn't permitted to request an authorization code. 客户端应用程序未注册到 Azure AD 中或者未添加到用户的 Azure AD 租户时,通常会出现此错误。This error usually occurs when the client application isn't registered in Azure AD or isn't added to the user's Azure AD tenant. 应用程序可以提示用户,并说明如何安装应用程序并将其添加到 Azure AD。The application can prompt the user with instruction for installing the application and adding it to Azure AD.
access_denied 资源所有者拒绝了许可Resource owner denied consent 客户端应用程序可以通知用户,除非用户许可,否则无法继续。The client application can notify the user that it can't proceed unless the user consents.
unsupported_response_type 授权服务器不支持请求中的响应类型。The authorization server does not support the response type in the request. 修复并重新提交请求。Fix and resubmit the request. 这通常是在初始测试期间捕获的开发错误。This is a development error typically caught during initial testing.
server_error 服务器遇到意外的错误。The server encountered an unexpected error. 重试请求。Retry the request. 这些错误可能是临时状况导致的。These errors can result from temporary conditions. 客户端应用程序可能向用户说明,其响应由于临时错误而延迟。The client application might explain to the user that its response is delayed to a temporary error.
temporarily_unavailable 服务器暂时繁忙,无法处理请求。The server is temporarily too busy to handle the request. 重试请求。Retry the request. 客户端应用程序可能向用户说明,其响应由于临时状况而延迟。The client application might explain to the user that its response is delayed because of a temporary condition.
invalid_resource 目标资源无效,原因是它不存在,Azure AD 找不到它,或者未正确配置。The target resource is invalid because it does not exist, Azure AD can't find it, or it's not correctly configured. 此错误表示未在租户中配置该资源(如果存在)。This error indicates the resource, if it exists, has not been configured in the tenant. 应用程序可以提示用户,并说明如何安装应用程序并将其添加到 Azure AD。The application can prompt the user with instruction for installing the application and adding it to Azure AD.
login_required 找到的用户太多或未找到任何用户Too many or no users found 客户端请求了静默身份验证 (prompt=none),但找不到单个用户。The client requested silent authentication (prompt=none), but a single user could not found. 这可能表示会话中有多个处于活动状态的用户或无用户。This may mean there are multiple users active in the session, or no users. 这将考虑所选租户。This takes into account the tenant chosen.
interaction_required 请求需要用户交互。The request requires user interaction. 需要额外的身份验证步骤或许可。An additional authentication step or consent is required. 请在没有 prompt=none 的情况下重试请求。Retry the request without prompt=none.

请求访问令牌Request an access token

现在已获取 authorization_code 并获得用户授权,可兑换 code 以获取所需资源的 access_tokenNow that you've acquired an authorization_code and have been granted permission by the user, you can redeem the code for an access_token to the desired resource. 通过向 /token 终结点发送 POST 请求来完成此操作:Do this by sending a POST request to the /token endpoint:

// Line breaks for legibility only

POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.partner.microsoftonline.cn
Content-Type: application/x-www-form-urlencoded

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong 
&client_secret=JqQX2PNo9bpM0uEihUPzyrh    // NOTE: Only required for web apps. This secret needs to be URL-Encoded.

提示

尝试在 Postman 中执行此请求!Try executing this request in Postman! (请不要忘记替换 code尝试在 Postman 中运行此请求(Don't forget to replace the code) Try running this request in Postman

参数Parameter 必需/可选Required/optional 说明Description
tenant 必需required 请求路径中的 {tenant} 值可用于控制哪些用户可以登录应用程序。The {tenant} value in the path of the request can be used to control who can sign into the application. 可以使用的值包括 commonorganizationsconsumers 和租户标识符。The allowed values are common, organizations, consumers, and tenant identifiers. 有关详细信息,请参阅协议基础知识For more detail, see protocol basics.
client_id 必填required Azure 门户 - 应用注册页分配给应用的应用程序(客户端)ID。The Application (client) ID that the Azure portal - App registrations page assigned to your app.
grant_type 必填required 必须是授权代码流的 authorization_codeMust be authorization_code for the authorization code flow.
scope 可选optional 范围的空格分隔列表。A space-separated list of scopes. 范围必须全部来自单个资源,以及 OIDC范围(profileopenidemail)。The scopes must all be from a single resource, along with OIDC scopes (profile, openid, email). 有关范围更加详细的说明,请参阅权限、许可和范围For a more detailed explanation of scopes, refer to permissions, consent, and scopes. 这是授权代码流的 Microsoft 扩展,旨在允许应用在令牌兑换期间声明其需要令牌的资源。This is a Microsoft extension to the authorization code flow, intended to allow apps to declare the resource they want the token for during token redemption.
code 必填required 在流的第一个阶段中获取的 authorization_code。The authorization_code that you acquired in the first leg of the flow.
redirect_uri 必需required 用于获取 authorization_code 的相同 redirect_uri 值。The same redirect_uri value that was used to acquire the authorization_code.
client_secret 机密 Web 应用所需required for confidential web apps 在应用注册门户中为应用创建的应用程序机密。The application secret that you created in the app registration portal for your app. 不应在本机应用或单页应用中使用应用程序密钥,因为 client_secrets 无法可靠地存储在设备或网页上。You shouldn't use the application secret in a native app or single page app because client_secrets can't be reliably stored on devices or web pages. Web 应用和 Web API 都需要应用程序密钥,它能够将 client_secret 安全地存储在服务器端。It's required for web apps and web APIs, which have the ability to store the client_secret securely on the server side. 在发送客户端密码之前必须对其进行 URL 编码。The client secret must be URL-encoded before being sent. 有关 URI 编码的详细信息,请参阅 URI 常规语法规范For more information on uri encoding, see the URI Generic Syntax specification.
code_verifier 建议recommended 即用于获取 authorization_code 的 code_verifier。The same code_verifier that was used to obtain the authorization_code. 如果在授权码授权请求中使用 PKCE,则需要。Required if PKCE was used in the authorization code grant request. 有关详细信息,请参阅 PKCE RFCFor more information, see the PKCE RFC.

成功的响应Successful response

成功的令牌响应如下:A successful token response will look like:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "token_type": "Bearer",
    "expires_in": 3599,
    "scope": "https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2Fmail.read",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD...",
}
参数Parameter 说明Description
access_token 请求的访问令牌。The requested access token. 应用可以使用此令牌验证受保护的资源,例如 Web API。The app can use this token to authenticate to the secured resource, such as a web API.
token_type 指示令牌类型值。Indicates the token type value. Azure AD 唯一支持的类型是 BearerThe only type that Azure AD supports is Bearer
expires_in 访问令牌的有效期(以秒为单位)。How long the access token is valid (in seconds).
scope access_token 的有效范围。The scopes that the access_token is valid for. 可选 - 这是非标准的,如果省略,令牌将用于流的初始阶段中所请求的范围。Optional - this is non-standard, and if omitted the token will be for the scopes requested on the initial leg of the flow.
refresh_token OAuth 2.0 刷新令牌。An OAuth 2.0 refresh token. 应用可以使用此令牌,在当前的访问令牌过期之后获取其他访问令牌。The app can use this token acquire additional access tokens after the current access token expires. Refresh_tokens 的生存期很长,而且可以用于延长保留资源访问权限的时间。Refresh_tokens are long-lived, and can be used to retain access to resources for extended periods of time. 有关刷新访问令牌的详细信息,请参阅以下部分For more detail on refreshing an access token, refer to the section below.
注意: 仅当已请求 offline_access 作用域时提供。Note: Only provided if offline_access scope was requested.
id_token JSON Web 令牌 (JWT)。A JSON Web Token (JWT). 应用可以解码此令牌的段,以请求已登录用户的相关信息。The app can decode the segments of this token to request information about the user who signed in. 应用可以缓存并显示值,机密客户端可以使用这些值进行授权。The app can cache the values and display them, and confidential clients can use this for authorization. 有关 id_tokens 的详细信息,请参阅 id_token referenceFor more information about id_tokens, see the id_token reference.
注意: 仅当已请求 openid 作用域时提供。Note: Only provided if openid scope was requested.

错误响应Error response

错误响应如下所示:Error responses will look like:

{
  "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: 255d1aef-8c98-452f-ac51-23d051240864\r\nCorrelation ID: fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7\r\nTimestamp: 2016-01-09 02:02:12Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2016-01-09 02:02:12Z",
  "trace_id": "255d1aef-8c98-452f-ac51-23d051240864",
  "correlation_id": "fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7"
}
参数Parameter 说明Description
error 可用于分类发生的错误类型与响应错误的错误码字符串。An error code string that can be used to classify types of errors that occur, and can be used to react to errors.
error_description 帮助开发人员识别身份验证错误根本原因的特定错误消息。A specific error message that can help a developer identify the root cause of an authentication error.
error_codes 可帮助诊断的 STS 特定错误代码列表。A list of STS-specific error codes that can help in diagnostics.
timestamp 发生错误的时间。The time at which the error occurred.
trace_id 可帮助诊断的请求唯一标识符。A unique identifier for the request that can help in diagnostics.
correlation_id 可帮助跨组件诊断的请求唯一标识符。A unique identifier for the request that can help in diagnostics across components.

令牌终结点错误的错误代码Error codes for token endpoint errors

错误代码Error Code 说明Description 客户端操作Client Action
invalid_request 协议错误,例如,缺少必需的参数。Protocol error, such as a missing required parameter. 修复请求或应用注册,然后重新提交请求Fix the request or app registration and resubmit the request
invalid_grant 授权代码或 PKCE 代码验证程序无效或已过期。The authorization code or PKCE code verifier is invalid or has expired. 尝试向 /authorize 终结点发送新请求,并验证 code_verifier 参数是否正确。Try a new request to the /authorize endpoint and verify that the code_verifier parameter was correct.
unauthorized_client 经过身份验证的客户端无权使用此权限授予类型。The authenticated client isn't authorized to use this authorization grant type. 客户端应用程序未注册到 Azure AD 中或者未添加到用户的 Azure AD 租户时,通常会出现这种情况。This usually occurs when the client application isn't registered in Azure AD or isn't added to the user's Azure AD tenant. 应用程序可以提示用户,并说明如何安装应用程序并将其添加到 Azure AD。The application can prompt the user with instruction for installing the application and adding it to Azure AD.
invalid_client 客户端身份验证失败。Client authentication failed. 客户端凭据无效。The client credentials aren't valid. 若要修复,应用程序管理员应更新凭据。To fix, the application administrator updates the credentials.
unsupported_grant_type 授权服务器不支持权限授予类型。The authorization server does not support the authorization grant type. 更改请求中的授权类型。Change the grant type in the request. 这种类型的错误应该只在开发过程中发生,并且应该在初始测试过程中检测到。This type of error should occur only during development and be detected during initial testing.
invalid_resource 目标资源无效,原因是它不存在,Azure AD 找不到它,或者未正确配置。The target resource is invalid because it does not exist, Azure AD can't find it, or it's not correctly configured. 这表示未在租户中配置该资源(如果存在)。This indicates the resource, if it exists, has not been configured in the tenant. 应用程序可以提示用户,并说明如何安装应用程序并将其添加到 Azure AD。The application can prompt the user with instruction for installing the application and adding it to Azure AD.
interaction_required 非标准,因为 OIDC 规范仅在 /authorize 终结点上调用它。请求需要用户交互。Non-standard, as the OIDC specification calls for this only on the /authorize endpoint.The request requires user interaction. 例如,需要额外的身份验证步骤。For example, an additional authentication step is required. 使用同一范围重试 /authorize 请求。Retry the /authorize request with the same scopes.
temporarily_unavailable 服务器暂时繁忙,无法处理请求。The server is temporarily too busy to handle the request. 请在短暂延迟后重试该请求。Retry the request after a small delay. 客户端应用程序可能向用户说明,其响应由于临时状况而延迟。The client application might explain to the user that its response is delayed because of a temporary condition.
consent_required 请求需要用户同意。The request requires user consent. 此错误是非标准错误,因为根据 OIDC 规范,它通常仅在 /authorize 终结点上返回。This error is non-standard, as it's usually only returned on the /authorize endpoint per OIDC specifications. 在客户端应用无权请求的代码兑换流上使用 scope 参数时返回。Returned when a scope parameter was used on the code redemption flow that the client app does not have permission to request. 客户端应将用户发送回具有正确范围的 /authorize 终结点,以便触发同意。The client should send the user back to the /authorize endpoint with the correct scope in order to trigger consent.
invalid_scope 应用请求的范围无效。The scope requested by the app is invalid. 将身份验证请求中的 scope 参数值更新为有效值。Update the value of the scope parameter in the authentication request to a valid value.

备注

单页应用可能会收到 invalid_request 错误,指明仅“单页应用程序”客户端类型允许进行跨源令牌兑换。Single page apps may receive an invalid_request error indicating that cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. 这表明用于请求令牌的重定向 URI 未标记为 spa 重定向 URI。This indicates that the redirect URI used to request the token has not been marked as a spa redirect URI. 有关如何启用此流的信息,请查看应用程序注册步骤Review the application registration steps on how to enable this flow.

使用访问令牌Use the access token

现已成功获取 access_token,可以通过在 Authorization 标头中包含令牌,在 Web API 的请求中使用令牌:Now that you've successfully acquired an access_token, you can use the token in requests to web APIs by including it in the Authorization header:

提示

在 Postman 中执行此请求!Execute this request in Postman! (先替换 Authorization 标头)尝试在 Postman 中运行此请求(Replace the Authorization header first) Try running this request in Postman

GET /v1.0/me/messages
Host: https://microsoftgraph.chinacloudapi.cn
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...

刷新访问令牌Refresh the access token

Access_token 生存期很短,必须在其过期后刷新,才能继续访问资源。Access_tokens are short lived, and you must refresh them after they expire to continue accessing resources. 为此,可以向 /token 终结点提交另一个 POST 请求,但这次要提供 refresh_token 而不是 codeYou can do so by submitting another POST request to the /token endpoint, this time providing the refresh_token instead of the code. 刷新令牌对客户端已获得同意的所有权限有效 - 因此,对 scope=mail.read 请求发出的刷新令牌可用于请求 scope=api://contoso.com/api/UseResource 的新访问令牌。Refresh tokens are valid for all permissions that your client has already received consent for - thus, a refresh token issued on a request for scope=mail.read can be used to request a new access token for scope=api://contoso.com/api/UseResource.

Web 应用和本机应用的刷新令牌没有指定的生存期。Refresh tokens for web apps and native apps do not have specified lifetimes. 通常,刷新令牌的生存期相对较长。Typically, the lifetimes of refresh tokens are relatively long. 但是,在某些情况下,刷新令牌会过期、被吊销,或缺少执行所需操作的足够权限。However, in some cases, refresh tokens expire, are revoked, or lack sufficient privileges for the desired action. 应用程序需要正确预期和处理令牌颁发终结点返回的错误Your application needs to expect and handle errors returned by the token issuance endpoint correctly. 但是,单页应用会获得一个生存期为 24 小时的令牌,每天需要新的身份验证。Single page apps, however, get a token with a 24 hour lifetime, requiring a new authentication every day. 当第三方 cookie 处于启用状态时,可以在 iframe 中静默完成此操作,但必须在没有第三方 cookie 的浏览器(如 Safari)的顶级框架中完成。This can be done silently in an iframe when 3rd party cookies are enabled, but must be done in a top level frame (either full page navigation or a popup) in browsers without 3rd party cookies such as Safari.

尽管刷新令牌在用于获取新的访问令牌时不会被撤销,但应放弃旧的刷新令牌。Although refresh tokens aren't revoked when used to acquire new access tokens, you are expected to discard the old refresh token. OAuth 2.0 规范指出:“授权服务器可能会发出新的刷新令牌,在这种情况下,客户端必须丢弃旧的刷新令牌,并将其替换为新的刷新令牌。The OAuth 2.0 spec says: "The authorization server MAY issue a new refresh token, in which case the client MUST discard the old refresh token and replace it with the new refresh token. 向客户端颁发新的刷新令牌后,授权服务器可能会撤销旧的刷新令牌。”The authorization server MAY revoke the old refresh token after issuing a new refresh token to the client."

重要

对于发送到已注册为 spa 的重定向 URI 的刷新令牌,刷新令牌将在 24 小时后过期。For refresh tokens sent to a redirect URI registered as spa, the refresh token will expire after 24 hours. 使用初始刷新令牌获取的其他刷新令牌将超过该过期时间,因此应用必须准备好使用交互式身份验证重新运行授权代码流,以每隔 24 小时获取一个新的刷新令牌。Additional refresh tokens acquired using the initial refresh token will carry over that expiration time, so apps must be prepared to re-run the authorization code flow using an interactive authentication to get a new refresh token every 24 hours. 用户无需输入其凭据,通常也不会看到任何 UX,只需重新加载应用程序,但浏览器必须访问顶级框架中的登录页,才能看到登录会话。Users do not have to enter their credentials, and will usually not even see any UX, just a reload of your application - but the browser must visit the login page in a top level frame in order to see the login session. 这是由阻止第三方 cookie 的浏览器中的隐私功能造成的。This is due to privacy features in browsers that block 3rd party cookies.


// Line breaks for legibility only

POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.partner.microsoftonline.cn
Content-Type: application/x-www-form-urlencoded

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2Fmail.read
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&grant_type=refresh_token
&client_secret=JqQX2PNo9bpM0uEihUPzyrh      // NOTE: Only required for web apps. This secret needs to be URL-Encoded

提示

尝试在 Postman 中执行此请求!Try executing this request in Postman! (请不要忘记替换 refresh_token尝试在 Postman 中运行此请求(Don't forget to replace the refresh_token) Try running this request in Postman

参数Parameter 类型Type 说明Description
tenant 必需required 请求路径中的 {tenant} 值可用于控制哪些用户可以登录应用程序。The {tenant} value in the path of the request can be used to control who can sign into the application. 可以使用的值包括 commonorganizationsconsumers 和租户标识符。The allowed values are common, organizations, consumers, and tenant identifiers. 有关详细信息,请参阅协议基础知识For more detail, see protocol basics.
client_id 必填required Azure 门户 - 应用注册体验分配给应用的应用程序(客户端)IDThe Application (client) ID that the Azure portal - App registrations experience assigned to your app.
grant_type 必需required 必须是授权代码流的此阶段的 refresh_tokenMust be refresh_token for this leg of the authorization code flow.
scope 必需required 范围的空格分隔列表。A space-separated list of scopes. 在此阶段请求的范围必须等效于原始 authorization_code 请求阶段中所请求的范围,或者为该范围的子集。The scopes requested in this leg must be equivalent to or a subset of the scopes requested in the original authorization_code request leg. 如果这个请求中指定的范围遍及多个资源服务器,Microsoft 标识平台终结点将返回第一个范围内所指定资源的令牌。If the scopes specified in this request span multiple resource server, then the Microsoft identity platform endpoint will return a token for the resource specified in the first scope. 有关范围更加详细的说明,请参阅权限、许可和范围For a more detailed explanation of scopes, refer to permissions, consent, and scopes.
refresh_token 必需required 在流的第二个阶段获取的 refresh_token。The refresh_token that you acquired in the second leg of the flow.
client_secret 必填(对于 Web 应用)required for web apps 在应用注册门户中为应用创建的应用程序机密。The application secret that you created in the app registration portal for your app. 它不应用于本机应用,因为设备无法可靠地存储 client_secrets。It should not be used in a native app, because client_secrets can't be reliably stored on devices. Web 应用和 Web API 都需要应用程序密钥,它能够将 client_secret 安全地存储在服务器端。It's required for web apps and web APIs, which have the ability to store the client_secret securely on the server side. 此机密需要进行 URL 编码。This secret needs to be URL-Encoded. 有关详细信息,请参阅 URI 一般语法规范For more information, see the URI Generic Syntax specification.

成功的响应Successful response

成功的令牌响应如下:A successful token response will look like:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "token_type": "Bearer",
    "expires_in": 3599,
    "scope": "https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2Fmail.read",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD...",
}
参数Parameter 说明Description
access_token 请求的访问令牌。The requested access token. 应用可以使用此令牌验证受保护的资源,例如 Web API。The app can use this token to authenticate to the secured resource, such as a web API.
token_type 指示令牌类型值。Indicates the token type value. Azure AD 唯一支持的类型是 BearerThe only type that Azure AD supports is Bearer
expires_in 访问令牌的有效期(以秒为单位)。How long the access token is valid (in seconds).
scope access_token 的有效范围。The scopes that the access_token is valid for.
refresh_token 新的 OAuth 2.0 刷新令牌。A new OAuth 2.0 refresh token. 应该将旧刷新令牌替换为新获取的这个刷新令牌,以确保刷新令牌的有效期尽可能地长。You should replace the old refresh token with this newly acquired refresh token to ensure your refresh tokens remain valid for as long as possible.
注意: 仅当已请求 offline_access 作用域时提供。Note: Only provided if offline_access scope was requested.
id_token 无符号 JSON Web 令牌 (JWT)。An unsigned JSON Web Token (JWT). 应用可以解码此令牌的段,以请求已登录用户的相关信息。The app can decode the segments of this token to request information about the user who signed in. 应用可以缓存并显示值,但不应依赖于这些值获取任何授权或安全边界。The app can cache the values and display them, but it should not rely on them for any authorization or security boundaries. 有关 id_tokens 的详细信息,请参阅 id_token referenceFor more information about id_tokens, see the id_token reference.
注意: 仅当已请求 openid 作用域时提供。Note: Only provided if openid scope was requested.

错误响应Error response

{
  "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: 255d1aef-8c98-452f-ac51-23d051240864\r\nCorrelation ID: fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7\r\nTimestamp: 2016-01-09 02:02:12Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2016-01-09 02:02:12Z",
  "trace_id": "255d1aef-8c98-452f-ac51-23d051240864",
  "correlation_id": "fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7"
}
参数Parameter 说明Description
error 可用于分类发生的错误类型与响应错误的错误码字符串。An error code string that can be used to classify types of errors that occur, and can be used to react to errors.
error_description 帮助开发人员识别身份验证错误根本原因的特定错误消息。A specific error message that can help a developer identify the root cause of an authentication error.
error_codes 可帮助诊断的 STS 特定错误代码列表。A list of STS-specific error codes that can help in diagnostics.
timestamp 发生错误的时间。The time at which the error occurred.
trace_id 可帮助诊断的请求唯一标识符。A unique identifier for the request that can help in diagnostics.
correlation_id 可帮助跨组件诊断的请求唯一标识符。A unique identifier for the request that can help in diagnostics across components.

有关错误代码的描述和建议的客户端操作,请参阅 令牌终结点错误的错误代码For a description of the error codes and the recommended client action, see Error codes for token endpoint errors.