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. 本指南与语言无关,介绍在不使用任何 Azure 开放源代码身份验证库的情况下,如何发送和接收 HTTP 消息。This guide is language-independent, and describes how to send and receive HTTP messages without using any of the Azure open-source authentication libraries.

本文介绍如何在应用程序中直接针对协议进行编程。This article describes how to program directly against the protocol in your application. 如果可能,建议你改用受支持的 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.

Note

Microsoft 标识平台终结点并非支持所有 Azure Active Directory 方案和功能。Not all Azure Active Directory scenarios & features are supported by the Microsoft identity platform endpoint. 若要确定是否应使用 Microsoft 标识平台终结点,请阅读 Microsoft 标识平台限制To determine if you should use the Microsoft identity platform endpoint, read about Microsoft identity platform limitations.

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 web apps and natively installed apps. 通过此流,应用能安全地获取 access_tokens,用于访问由 Microsoft 标识平台终结点保护的资源。The flow enables apps to securely acquire access_tokens that can be used to access resources secured by the Microsoft identity platform endpoint.

协议图Protocol diagram

从较高层面讲,本机/移动应用程序的整个身份验证流有点类似于:At a high level, the entire authentication flow for a native/mobile application looks a bit like this:

OAuth 授权代码流

请求授权代码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 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

Tip

单击下面的链接以执行此请求!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 可以是 consumersorganizations 之一。Can be one of consumers or organizations.

如果包含,它跳过用户在登录页上经历的基于电子邮件的发现过程,导致稍微更加流畅的用户体验。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. 通常,应用将在重新身份验证期间使用此参数,方法是从上次登录提取 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_method 可选optional 用于为 code_challenge 参数编码 code_verifier 的方法。The method used to encode the code_verifier for the code_challenge parameter. 可以是以下值之一:Can be one of the following values:

- plain
- S256

如果已排除在外,且包含了 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.
code_challenge 可选optional 用于通过本地客户端的 Proof Key for Code Exchange (PKCE) 保护授权代码授权。Used to secure authorization code grants via Proof Key for Code Exchange (PKCE) from a native client. 如果包含 code_challenge_method,则需要。Required if code_challenge_method is included. 有关详细信息,请参阅 PKCE RFCFor more information, see the PKCE RFC.

此时,将请求用户输入凭据并完成身份验证。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.

错误响应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
&client_secret=JqQX2PNo9bpM0uEihUPzyrh    // NOTE: Only required for web apps. This secret needs to be URL-Encoded.

Tip

尝试在 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 必需required 范围的空格分隔列表。A space-separated list of scopes. 在此阶段请求的范围必须相当于或为第一个阶段中所请求的范围子集。The scopes requested in this leg must be equivalent to or a subset of the scopes requested in the first leg. 范围必须全部来自单个资源,以及 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.
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 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 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 编码。The client secret must be URL-encoded before being sent. 有关详细信息,请单击此处For more information click here.
code_verifier 可选optional 即用于获取 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.
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, 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 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 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 请求需要用户交互。The request requires user interaction. 例如,需要额外的身份验证步骤。For example, an additional authentication step is required. 使用同一资源重试请求。Retry the request with the same resource.
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.

使用访问令牌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:

Tip

在 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.

刷新令牌没有指定的生存期。Refresh tokens 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.

尽管刷新令牌在用于获取新访问令牌时不会被吊销,但预期你会丢弃旧的刷新令牌。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."

// 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

Tip

尝试在 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 说明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, for more information click here.

成功的响应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.