使用 Azure Active Directory B2C 中的 OAuth 2.0 隐式流的单页登录Single-page sign in using the OAuth 2.0 implicit flow in Azure Active Directory B2C

许多新式应用程序都有一个单页应用前端(主要以 JavaScript 编写)。Many modern applications have a single-page app front end that is written primarily in JavaScript. 通常,该应用可使用 React、Angular 或 Vue.js 等框架进行编写。Often, the app is written by using a framework like React, Angular, or Vue.js. 主要在浏览器上运行的单页应用和其他 JavaScript 应用在身份验证时还面临一些其他挑战:Single-page apps and other JavaScript apps that run primarily in a browser have some additional challenges for authentication:

  • 这些应用程序的安全特征与传统的基于服务器的 Web 应用程序不同。The security characteristics of these apps are different from traditional server-based web applications.
  • 许多授权服务器与标识提供者不支持跨源资源共享 (CORS) 请求。Many authorization servers and identity providers do not support cross-origin resource sharing (CORS) requests.
  • 重定向离开应用的完整网页浏览器可能会对用户体验具有侵略性。Full-page browser redirects away from the app can be invasive to the user experience.

为了支持这些应用程序,Azure Active Directory B2C (Azure AD B2C) 使用 OAuth 2.0 隐式流。To support these applications, Azure Active Directory B2C (Azure AD B2C) uses the OAuth 2.0 implicit flow. OAuth 2.0 规范第 4.2 部分描述了 OAuth 2.0 授权隐式授权流。The OAuth 2.0 authorization implicit grant flow is described in section 4.2 of the OAuth 2.0 specification. 在隐式流中,应用直接从 Azure Active Directory (Azure AD) 授权终结点接收令牌,无需任何服务器到服务器的交换。In implicit flow, the app receives tokens directly from the Azure Active Directory (Azure AD) authorize endpoint, without any server-to-server exchange. 所有身份验证逻辑和会话处理全部在 JavaScript 客户端中通过页面重定向或弹框执行。All authentication logic and session handling is done entirely in the JavaScript client with either a page redirect or a pop-up box.

Azure AD B2C 扩展了标准 OAuth 2.0 隐式流,使其功能远远超出了简单的身份验证和授权。Azure AD B2C extends the standard OAuth 2.0 implicit flow to more than simple authentication and authorization. Azure AD B2C 引入了策略参数Azure AD B2C introduces the policy parameter. 通过该策略参数,可以使用 OAuth 2.0 向应用添加策略,例如注册、登录和配置文件管理用户流。With the policy parameter, you can use OAuth 2.0 to add policies to your app, such as sign-up, sign-in, and profile management user flows. 在本文的示例 HTTP 请求中,使用了 {tenant}.partner.onmschina.cn 作为示例。In the example HTTP requests in this article, {tenant}.partner.onmschina.cn is used as an example. 如果你有一个租户并且还创建了用户流,请将 {tenant} 替换为该租户的名称。Replace {tenant} with the name of your tenant if you have one and have also created a user flow.

隐式登录流看起来类似于下图。The implicit sign-in flow looks something like the following figure. 本文后面将详细说明每个步骤。Each step is described in detail later in the article.

显示 OpenID Connect 隐式流的泳道样式示意图

发送身份验证请求Send authentication requests

当 Web 应用程序需要对用户进行身份验证并运行用户流时,它可以将用户定向到 /authorize 终结点。When your web application needs to authenticate the user and run a user flow, it can direct the user to the /authorize endpoint. 用户可以根据用户流执行操作。The user takes action depending on the user flow.

在此请求中,客户端在 scope 参数中指明需要从用户获取的权限以及要运行的用户流。In this request, the client indicates the permissions that it needs to acquire from the user in the scope parameter and the user flow to run. 若要了解该请求的工作原理,请尝试将该请求粘贴到浏览器中并运行它。To get a feel for how the request works, try pasting the request into a browser and running it. {tenant} 替换为 Azure AD B2C 租户的名称。Replace {tenant} with the name of your Azure AD B2C tenant. 90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 替换为之前在租户中注册的应用程序的应用程序 ID。Replace 90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 with the app ID of the application you've previously registered in your tenant. {policy} 替换为在租户中创建的策略的名称,例如 b2c_1_sign_inReplace {policy} with the name of a policy you've created in your tenant, for example b2c_1_sign_in.

GET https://{tenant}.b2clogin.cn/{tenant}.partner.onmschina.cn/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=id_token+token
&redirect_uri=https%3A%2F%2Faadb2cplayground.chinacloudsites.cn%2F
&response_mode=fragment
&scope=openid%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345
参数Parameter 必须Required 说明Description
{tenant}{tenant} Yes Azure AD B2C 租户的名称Name of your Azure AD B2C tenant
{policy}{policy} Yes 要运行的用户流。The user flow to be run. 指定在 Azure AD B2C 租户中创建的用户流的名称。Specify the name of a user flow you've created in your Azure AD B2C tenant. 例如:b2c_1_sign_inb2c_1_sign_upb2c_1_edit_profileFor example: b2c_1_sign_in, b2c_1_sign_up, or b2c_1_edit_profile.
client_idclient_id Yes Azure 门户分配给应用程序的应用程序 ID。The application ID that the Azure portal assigned to your application.
response_typeresponse_type Yes 必须包含 OpenID Connect 登录的 id_tokenMust include id_token for OpenID Connect sign-in. 也可以包含响应类型 tokenIt also can include the response type token. 如果使用 token,则应用能够立即从授权终结点接收访问令牌,而无需向授权终结点发出第二次请求。If you use token, your app can immediately receive an access token from the authorize endpoint, without making a second request to the authorize endpoint. 如果使用 token 响应类型,scope 参数必须包含一个范围,以指出要对哪个资源发出令牌。If you use the token response type, the scope parameter must contain a scope that indicates which resource to issue the token for.
redirect_uriredirect_uri No 应用的重定向 URI,应用可在其中发送和接收身份验证响应。The redirect URI of your app, where authentication responses can be sent and received by your app. 它必须完全匹配在门户中注册的其中一个重定向 URI,但必须经 URL 编码。It must exactly match one of the redirect URIs that you registered in the portal, except that it must be URL-encoded.
response_moderesponse_mode No 指定用于将生成的令发送回应用的方法。Specifies the method to use to send the resulting token back to your app. 对于隐式流,使用 fragmentFor implicit flows, use fragment.
scopescope Yes 范围的空格分隔列表。A space-separated list of scopes. 一个范围值,该值向 Azure AD 指示正在请求的两个权限。A single scope value indicates to Azure AD both of the permissions that are being requested. openid 作用域表示允许使用 ID 令牌的形式使用户登录并获取有关用户的数据。The openid scope indicates a permission to sign in the user and get data about the user in the form of ID tokens. offline_access 作用域对 Web 应用是可选的。The offline_access scope is optional for web apps. 它表示你的应用需要刷新令牌才能长期访问资源。It indicates that your app needs a refresh token for long-lived access to resources.
statestate No 同时随令牌响应返回的请求中所包含的值。A value included in the request that also is returned in the token response. 它可以是你想要使用的任何内容的字符串。It can be a string of any content that you want to use. 随机生成的唯一值通常用于防止跨站点请求伪造攻击。Usually, a randomly generated, unique value is used, to prevent cross-site request forgery attacks. 该状态也用于在身份验证请求出现之前,在应用中编码用户的状态信息,例如用户之前所在的页面。The state is also used to encode information about the user's state in the app before the authentication request occurred, like the page they were on.
noncenonce Yes 由应用生成且包含在请求中的值,以声明方式包含在生成的 ID 令牌中。A value included in the request (generated by the app) that is included in the resulting ID token as a claim. 应用程序接着便可确认此值,以减少令牌重新执行攻击。The app can then verify this value to mitigate token replay attacks. 此值通常是随机产生的唯一字符串,可用于识别请求的来源。Usually, the value is a randomized, unique string that can be used to identify the origin of the request.
promptprompt No 需要的用户交互类型。The type of user interaction that's required. 目前唯一有效的值是 loginCurrently, the only valid value is login. 此参数会强制用户在该请求上输入其凭据。This parameter forces the user to enter their credentials on that request. 单一登录不会生效。Single sign-on doesn't take effect.

此时,要求用户完成策略的工作流。At this point, the user is asked to complete the policy's workflow. 用户可能必须输入其用户名和密码、用社交标识登录、注册目录或者执行任何其他数目的步骤。The user might have to enter their username and password, sign in with a social identity, sign up for the directory, or any other number of steps. 用户操作取决于用户流是如何定义的。User actions depend on how the user flow is defined.

用户完成用户流后,Azure AD 会在你用于 redirect_uri 的值处将响应返回到应用。After the user completes the user flow, Azure AD returns a response to your app at the value you used for redirect_uri. 它使用在 response_mode 参数中指定的方法。It uses the method specified in the response_mode parameter. 对于每种用户操作情况,响应完全相同,与执行的用户流无关。The response is exactly the same for each of the user action scenarios, independent of the user flow that was executed.

成功的响应Successful response

使用 response_mode=fragmentresponse_type=id_token+token 的成功响应如下所示(包含换行符以便阅读):A successful response that uses response_mode=fragment and response_type=id_token+token looks like the following, with line breaks for legibility:

GET https://aadb2cplayground.chinacloudsites.cn/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&token_type=Bearer
&expires_in=3599
&scope="90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access",
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=arbitrary_data_you_sent_earlier
参数Parameter 说明Description
access_tokenaccess_token 应用请求的访问令牌。The access token that the app requested.
token_typetoken_type 令牌类型值。The token type value. Azure AD 唯一支持的类型是 Bearer。The only type that Azure AD supports is Bearer.
expires_inexpires_in 访问令牌有效的时间长度(以秒为单位)。The length of time that the access token is valid (in seconds).
scopescope 令牌的有效范围。The scopes that the token is valid for. 还可使用范围来缓存令牌,以供以后使用。You also can use scopes to cache tokens for later use.
id_tokenid_token 应用请求的 ID 令牌。The ID token that the app requested. 可以使用 ID 令牌验证用户的标识,开始与用户建立会话。You can use the ID token to verify the user's identity and begin a session with the user. 有关 ID 令牌及其内容的详细信息,请参阅 Azure AD B2C 令牌参考For more information about ID tokens and their contents, see the Azure AD B2C token reference.
statestate 如果请求中包含 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

错误响应也可能发送到重定向 URI,让应用能够对其进行适当处理:Error responses also can be sent to the redirect URI so that the app can handle them appropriately:

GET https://aadb2cplayground.chinacloudsites.cn/#
error=access_denied
&error_description=the+user+canceled+the+authentication
&state=arbitrary_data_you_can_receive_in_the_response
参数Parameter 说明Description
errorerror 一个代码,用于对发生的错误类型进行分类。A code used to classify types of errors that occur.
error_descriptionerror_description 帮助识别身份验证错误根本原因的特定错误消息。A specific error message that can help you identify the root cause of an authentication error.
statestate 如果请求中包含 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 令牌Validate the ID token

收到 ID 令牌并不表示可以对用户进行身份验证。Receiving an ID token is not enough to authenticate the user. 根据应用的要求验证 ID 令牌的签名和令牌中的声明。Validate the ID token's signature, and verify the claims in the token per your app's requirements. Azure AD B2C 使用 JSON Web 令牌 (JWT) 和公钥加密对令牌进行签名并验证其是否有效。Azure AD B2C uses JSON Web Tokens (JWTs) and public key cryptography to sign tokens and verify that they are valid.

许多开放源代码库都可用于验证 JWT,具体取决于首选使用的语言。Many open-source libraries are available for validating JWTs, depending on the language you prefer to use. 请考虑浏览可用的开放源代码库,而不是实现自己的验证逻辑。Consider exploring available open-source libraries rather than implementing your own validation logic. 可以使用本文中的信息了解如何正确使用这些库。You can use the information in this article to help you learn how to properly use those libraries.

Azure AD B2C 具有 OpenID Connect 元数据终结点。Azure AD B2C has an OpenID Connect metadata endpoint. 应用可以使用终结点在运行时提取 Azure AD B2C 的相关信息。An app can use the endpoint to fetch information about Azure AD B2C at runtime. 此信息包括终结点、令牌内容和令牌签名密钥。This information includes endpoints, token contents, and token signing keys. Azure AD B2C 租户中的每个用户流都有一个 JSON 元数据文档。There is a JSON metadata document for each user flow in your Azure AD B2C tenant. 例如,fabrikamb2c.partner.onmschina.cn 租户中的 b2c_1_sign_in 用户流的元数据文档位于以下位置:For example, the metadata document for the b2c_1_sign_in user flow in the fabrikamb2c.partner.onmschina.cn tenant is located at:

https://fabrikamb2c.b2clogin.cn/fabrikamb2c.partner.onmschina.cn/b2c_1_sign_in/v2.0/.well-known/openid-configuration

此配置文档的其中一个属性是 jwks_uriOne of the properties of this configuration document is the jwks_uri. 相同用户流的值是:The value for the same user flow would be:

https://fabrikamb2c.b2clogin.cn/fabrikamb2c.partner.onmschina.cn/b2c_1_sign_in/discovery/v2.0/keys

若要确定对 ID 令牌签名所用的用户流(以及提取元数据的位置),共有两个选择。To determine which user flow was used to sign an ID token (and where to fetch the metadata from), you have two options. 第一种方法,用户流名称包含在 id_tokenacr 声明中。First, the user flow name is included in the acr claim in id_token. 有关如何从 ID 令牌中分析声明的信息,请参阅 Azure AD B2C 令牌参考For information about how to parse the claims from an ID token, see the Azure AD B2C token reference. 另一个方法是在发出请求时在 state 参数的值中对用户流进行编码。Your other option is to encode the user flow in the value of the state parameter when you issue the request. 然后对 state 参数进行解码以确定所使用的用户流。Then, decode the state parameter to determine which user flow was used. 任意一种方法均有效。Either method is valid.

从 OpenID Connect 元数据终结点获取元数据文档后,可以使用 RSA-256 公钥(位于此终结点上)来验证 ID 令牌的签名。After you've acquired the metadata document from the OpenID Connect metadata endpoint, you can use the RSA-256 public keys (located at this endpoint) to validate the signature of the ID token. 在任何给定的时间,此终结点上可能列出多个密钥,每个密钥使用 kid 进行标识。There might be multiple keys listed at this endpoint at any given time, each identified by a kid. id_token 的标头还包含 kid 声明。The header of id_token also contains a kid claim. 它指示这些键中的哪一个用于对 ID 令牌进行签名。It indicates which of these keys was used to sign the ID token. 有关详细信息(包括了解验证令牌),请参阅 Azure AD B2C 令牌参考For more information, including learning about validating tokens, see the Azure AD B2C token reference.

在验证 ID 令牌的签名后,需要验证几个声明。After you validate the signature of the ID token, several claims require verification. 例如:For example:

  • 验证 nonce 声明以防止令牌重放攻击。Validate the nonce claim to prevent token replay attacks. 其值应为在登录请求中指定的内容。Its value should be what you specified in the sign-in request.
  • 验证 aud 声明以确保已为应用颁发 ID 令牌。Validate the aud claim to ensure that the ID token was issued for your app. 其值应为应用的应用程序 ID。Its value should be the application ID of your app.
  • 验证 iatexp 声明以确保 ID 令牌未过期。Validate the iat and exp claims to ensure that the ID token has not expired.

其他一些需要执行的验证在 OpenID Connect 核心规范中有详细说明。根据情况,可能还希望验证其他声明。Several more validations that you should perform are described in detail in the OpenID Connect Core Spec. You might also want to validate additional claims, depending on your scenario. 一些常见的验证包括:Some common validations include:

  • 确保用户或组织已注册应用。Ensuring that the user or organization has signed up for the app.
  • 确保用户拥有正确的授权和权限。Ensuring that the user has proper authorization and privileges.
  • 确保执行了一定强度的身份验证,例如使用 Azure 多重身份验证。Ensuring that a certain strength of authentication has occurred, such as by using Azure Multi-Factor Authentication.

有关 ID 令牌中声明的详细信息,请参阅 Azure AD B2C 令牌参考For more information about the claims in an ID token, see the Azure AD B2C token reference.

验证 ID 令牌后,可以开始与用户的会话。After you have validated the ID token, you can begin a session with the user. 在应用中,使用 ID 令牌中的声明来获取用户的相关信息。In your app, use the claims in the ID token to obtain information about the user. 此信息可以用于显示、记录和授权等等。This information can be used for display, records, authorization, and so on.

获取访问令牌Get access tokens

如果 Web 应用唯一需要做的是执行用户流,则可以跳过下面几节。If the only thing your web apps needs to do is execute user flows, you can skip the next few sections. 下面几节中的信息仅适用于需要对 Web API 进行验证调用,并且受 Azure AD B2C 保护的 Web 应用。The information in the following sections is applicable only to web apps that need to make authenticated calls to a web API, and which are protected by Azure AD B2C.

将用户登录到单页应用后,便可获取访问令牌以调用受 Azure AD 保护的 Web API。Now that you've signed the user into your single-page app, you can get access tokens for calling web APIs that are secured by Azure AD. 即使已使用 token 响应类型收到令牌,也仍可以使用此方法获取其他资源的令牌,而无需再次将用户重定向到登录页。Even if you have already received a token by using the token response type, you can use this method to acquire tokens for additional resources without redirecting the user to sign in again.

在典型的 Web 应用流中,你将对 /token 终结点发出请求。In a typical web app flow, you would make a request to the /token endpoint. 但是,该终结点不支持 CORS 请求,因此进行 AJAX 调用以获取和刷新令牌并不可取。However, the endpoint does not support CORS requests, so making AJAX calls to get a refresh token is not an option. 相反,可以在隐藏的 HTML iframe 元素中使用隐式流,以获取其他 Web API 的新令牌。Instead, you can use the implicit flow in a hidden HTML iframe element to get new tokens for other web APIs. 下面是一个示例(带换行符以便阅读):Here's an example, with line breaks for legibility:

https://{tenant}.b2clogin.cn/{tenant}.partner.onmschina.cn/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=token
&redirect_uri=https%3A%2F%2Faadb2cplayground.chinacloudsites.cn%2F
&scope=https%3A%2F%2Fapi.contoso.com%2Ftasks.read
&response_mode=fragment
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345
&prompt=none
参数Parameter 必需?Required? 说明Description
{tenant}{tenant} 必须Required Azure AD B2C 租户的名称Name of your Azure AD B2C tenant
{policy}{policy} 必须Required 要运行的用户流。The user flow to be run. 指定在 Azure AD B2C 租户中创建的用户流的名称。Specify the name of a user flow you've created in your Azure AD B2C tenant. 例如:b2c_1_sign_inb2c_1_sign_upb2c_1_edit_profileFor example: b2c_1_sign_in, b2c_1_sign_up, or b2c_1_edit_profile.
client_idclient_id 必须Required Azure 门户中分配给应用的应用程序 ID。The application ID assigned to your app in the Azure portal.
response_typeresponse_type 必须Required 必须包含 OpenID Connect 登录的 id_tokenMust include id_token for OpenID Connect sign-in. 也可能包含响应类型 tokenIt might also include the response type token. 如果在此处使用 token,应用能够立即从授权终结点接收访问令牌,而无需向授权终结点发出第二次请求。If you use token here, your app can immediately receive an access token from the authorize endpoint, without making a second request to the authorize endpoint. 如果使用 token 响应类型,scope 参数必须包含一个范围,以指出要对哪个资源发出令牌。If you use the token response type, the scope parameter must contain a scope that indicates which resource to issue the token for.
redirect_uriredirect_uri 建议Recommended 应用的重定向 URI,应用可在其中发送和接收身份验证响应。The redirect URI of your app, where authentication responses can be sent and received by your app. 它必须与门户中注册的其中一个重定向 URI 完全匹配,否则必须经过 URL 编码。It must exactly match one of the redirect URIs you registered in the portal, except that it must be URL-encoded.
scopescope 必须Required 范围的空格分隔列表。A space-separated list of scopes. 若要获取令牌,请包含相应资源所需的所有范围。For getting tokens, include all scopes that you require for the intended resource.
response_moderesponse_mode 建议Recommended 指定用于将生成的令牌送回到应用的方法。Specifies the method that is used to send the resulting token back to your app. 对于隐式流,请使用 fragmentFor implicit flow, use fragment. 可以指定其他两种模式(queryform_post),但在隐式流中不起作用。Two other modes can be specified, query and form_post, but do not work in the implicit flow.
statestate 建议Recommended 随令牌响应返回的请求中所包含的值。A value included in the request that is returned in the token response. 它可以是你想要使用的任何内容的字符串。It can be a string of any content that you want to use. 随机生成的唯一值通常用于防止跨站点请求伪造攻击。Usually, a randomly generated, unique value is used, to prevent cross-site request forgery attacks. 它还可用于在身份验证请求发生前,对有关用户在应用中的状态信息进行编码。The state also is used to encode information about the user's state in the app before the authentication request occurred. 例如,用户之前所在的页面或视图。For example, the page or view the user was on.
noncenonce 必须Required 由应用生成且包含在请求中的值,以声明方式包含在生成的 ID 令牌 中。A value included in the request, generated by the app, that is included in the resulting ID token as a claim. 应用程序接着便可确认此值,以减少令牌重新执行攻击。The app can then verify this value to mitigate token replay attacks. 此值通常是随机产生的唯一字符串,可识别请求的来源。Usually, the value is a randomized, unique string that identifies the origin of the request.
promptprompt 必须Required 若要刷新并获取隐藏的 iframe 中的令牌,请使用 prompt=none 以确保 iframe 会立即返回,而不会停滞在登录页面上。To refresh and get tokens in a hidden iframe, use prompt=none to ensure that the iframe does not get stuck on the sign-in page, and returns immediately.
login_hintlogin_hint 必须Required 若要刷新并获取隐藏的 iframe 中的令牌,请在此提示中加入用户的用户名,以便区分用户在给定时间内可能具有的多个会话。To refresh and get tokens in a hidden iframe, include the username of the user in this hint to distinguish between multiple sessions the user might have at a given time. 可以使用 preferred_username 声明从以前的登录名中提取用户名(需要使用 profile 范围来接收 preferred_username 声明)。You can extract the username from an earlier sign-in by using the preferred_username claim (the profile scope is required in order to receive the preferred_username claim).
domain_hintdomain_hint 必须Required 可以是 consumersorganizationsCan be consumers or organizations. 若要刷新并获取隐藏的 iframe 中的令牌,请在请求中包含 domain_hint 值。For refreshing and getting tokens in a hidden iframe, include the domain_hint value in the request. 从以前登录名的 ID 令牌中提取 tid 声明,以确定要使用的值(需要使用 profile 范围来接收 tid 声明)。Extract the tid claim from the ID token of an earlier sign-in to determine which value to use (the profile scope is required in order to receive the tid claim). 如果 tid 声明值是 9188040d-6c67-4c5b-b112-36a304b66dad,请使用 domain_hint=consumersIf the tid claim value is 9188040d-6c67-4c5b-b112-36a304b66dad, use domain_hint=consumers. 否则使用 domain_hint=organizationsOtherwise, use domain_hint=organizations.

通过设置 prompt=none 参数,此请求会立即成功或立即失败,并返回到应用程序。By setting the prompt=none parameter, this request either succeeds or fails immediately, and returns to your application. 成功的响应会通过 response_mode 参数中指定的方法,发送到位于所指示的重定向 URI 的应用。A successful response is sent to your app at the indicated redirect URI, by using the method specified in the response_mode parameter.

成功的响应Successful response

使用 response_mode=fragment 的成功响应如以下示例所示:A successful response by using response_mode=fragment looks like this example:

GET https://aadb2cplayground.chinacloudsites.cn/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=arbitrary_data_you_sent_earlier
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fapi.contoso.com%2Ftasks.read
参数Parameter 说明Description
access_tokenaccess_token 应用请求的令牌。The token that the app requested.
token_typetoken_type 令牌类型始终是“持有者”。The token type will always be Bearer.
statestate 如果请求中包含 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.
expires_inexpires_in 访问令牌的有效期(以秒为单位)。How long the access token is valid (in seconds).
scopescope 访问令牌有效的范围。The scopes that the access token is valid for.

错误响应Error response

错误响应也可能发送到重定向 URI,使应用可以对其进行适当处理。Error responses also can be sent to the redirect URI so that the app can handle them appropriately. 对于 prompt=none,错误应如以下示例所示:For prompt=none, an expected error looks like this example:

GET https://aadb2cplayground.chinacloudsites.cn/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
参数Parameter 说明Description
errorerror 错误代码字符串,可用于对发生的错误类型进行分类。An error code string that can be used to classify types of errors that occur. 还可使用该字符串对错误作出响应。You also can use the string to react to errors.
error_descriptionerror_description 帮助识别身份验证错误根本原因的特定错误消息。A specific error message that can help you identify the root cause of an authentication error.

如果在 iframe 请求中收到此错误,用户必须再次以交互方式登录以检索新令牌。If you receive this error in the iframe request, the user must interactively sign in again to retrieve a new token.

刷新令牌Refresh tokens

ID 令牌和访问令牌在较短时间后都会过期。ID tokens and access tokens both expire after a short period of time. 应用必须准备好定期刷新这些令牌。Your app must be prepared to refresh these tokens periodically. 若要刷新任一类型的令牌,请使用 prompt=none 参数控制 Azure AD 步骤,执行我们在先前示例中使用的同一隐藏的 iframe 请求。To refresh either type of token, perform the same hidden iframe request we used in an earlier example, by using the prompt=none parameter to control Azure AD steps. 若要接收新的 id_token 值,请务必使用 response_type=id_tokenscope=openid,以及 nonce 参数。To receive a new id_token value, be sure to use response_type=id_token and scope=openid, and a nonce parameter.

发送注销请求Send a sign-out request

如果想要从应用中注销用户,请将用户重定向到 Azure AD 进行注销。如果不对用户进行重定向,用户可能不需要输入其凭据就能重新通过应用的身份验证,因为他们与 Azure AD 之间仍然存在有效的单一登录会话。When you want to sign the user out of the app, redirect the user to Azure AD to sign out. If you don't redirect the user, they might be able to reauthenticate to your app without entering their credentials again because they have a valid single sign-on session with Azure AD.

只需将用户重定向到验证 ID 令牌中所述的相同 OpenID Connect 元数据文档中列出的 end_session_endpointYou can simply redirect the user to the end_session_endpoint that is listed in the same OpenID Connect metadata document described in Validate the ID token. 例如:For example:

GET https://{tenant}.b2clogin.cn/{tenant}.partner.onmschina.cn/{policy}/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Faadb2cplayground.chinacloudsites.cn%2F
参数Parameter 必须Required 说明Description
{tenant}{tenant} Yes Azure AD B2C 租户的名称Name of your Azure AD B2C tenant
{policy}{policy} Yes 想要用于从应用程序中注销用户的用户流。The user flow that you want to use to sign the user out of your application.
post_logout_redirect_uripost_logout_redirect_uri No 用户在成功注销后应重定向到的 URL。如果未包含此参数,Azure AD B2C 会向用户显示一条常规消息。The URL that the user should be redirected to after successful sign out. If it isn't included, Azure AD B2C shows the user a generic message.
statestate No 如果请求中包含 state 参数,响应中就应该出现相同的值。If a state parameter is included in the request, the same value should appear in the response. 应用程序需验证请求和响应中的 state 值是否相同。The application should verify that the state values in the request and response are identical.

备注

将用户定向到 end_session_endpoint 会清除用户的某些 Azure AD B2C 单一登录状态。Directing the user to the end_session_endpoint clears some of the user's single sign-on state with Azure AD B2C. 但是,不会从用户的社交标识提供者会话中注销该用户。However, it doesn't sign the user out of the user's social identity provider session. 如果用户在后续登录中选择相同的标识提供者,用户将重新进行身份验证,且无需输入其凭据。If the user selects the same identity provider during a subsequent sign-in, the user is re-authenticated, without entering their credentials. 如果用户要注销 Azure AD B2C 应用程序,并不表示他们想要完全注销其帐户。If a user wants to sign out of your Azure AD B2C application, it does not necessarily mean they want to completely sign out of their account. 但是,如果是本地帐户,则会以正确的方式结束用户的会话。However, for local accounts, the user's session will be ended properly.

后续步骤Next steps

代码示例:Azure AD B2C(带有适用于 JavaScript 的 Microsoft 身份验证库)Code sample: Azure AD B2C with Microsoft Authentication Library for JavaScript

使用 msal.js 为 Azure AD B2C 构建的单页应用程序 (GitHub)Single-page application built with msal.js for Azure AD B2C (GitHub)

GitHub 上的此示例旨在帮助你在以 msal.js 构建的简单 Web 应用程序中开始使用 Azure AD B2C,以及使用弹出式身份验证。This sample on GitHub is intended to help get you started to Azure AD B2C in a simple web application built with msal.js and using pop-up-style authentication.