在 Azure Active Directory B2C 中请求访问令牌Request an access token in Azure Active Directory B2C

访问令牌包含的声明可在 Azure Active Directory B2C (Azure AD B2C) 中用于识别已授予的对 API 的权限。An access token contains claims that you can use in Azure Active Directory B2C (Azure AD B2C) to identify the granted permissions to your APIs. 调用资源服务器时,必须在 HTTP 请求中提供访问令牌。When calling a resource server, an access token must be present in the HTTP request. 访问令牌在 Azure AD B2C 的响应中以 access_token 表示。An access token is denoted as access_token in the responses from Azure AD B2C.

本文介绍如何请求 Web 应用程序和 Web API 的访问令牌。This article shows you how to request an access token for a web application and web API. 有关 Azure AD B2C 中令牌的详细信息,请参阅 Azure Active Directory B2C 中的令牌概述For more information about tokens in Azure AD B2C, see the overview of tokens in Azure Active Directory B2C.

备注

Web API 链(代理)不受 Azure AD B2C 支持。Web API chains (On-Behalf-Of) is not supported by Azure AD B2C. - 许多体系结构包含需要调用另一个下游 Web API 的 Web API,这两者都受 Azure AD B2C 的保护。- Many architectures include a web API that needs to call another downstream web API, both secured by Azure AD B2C. 此方案常见于包含 Web API 后端的客户端,该后端反过来会调用另一服务。This scenario is common in clients that have a web API back end, which in turn calls a another service. 可以使用 OAuth 2.0 JWT 持有者凭据授权(也称为代理流)来支持这种链接的 Web API 方案。This chained web API scenario can be supported by using the OAuth 2.0 JWT Bearer Credential grant, otherwise known as the On-Behalf-Of flow. 但是,Azure AD B2C 中目前尚未实现代理流。However, the On-Behalf-Of flow is not currently implemented in Azure AD B2C.

先决条件Prerequisites

作用域Scopes

可以通过作用域管理对受保护资源的权限。Scopes provide a way to manage permissions to protected resources. 在请求访问令牌时,客户端应用程序需要在请求的 scope 参数中指定所需的权限。When an access token is requested, the client application needs to specify the desired permissions in the scope parameter of the request. 例如,对于其“应用 ID URI”为 https://contoso.partner.onmschina.cn/api 的 API,若将“作用域值”指定为 read,则作用域为 https://contoso.partner.onmschina.cn/api/readFor example, to specify the Scope Value of read for the API that has the App ID URI of https://contoso.partner.onmschina.cn/api, the scope would be https://contoso.partner.onmschina.cn/api/read.

Web API 使用作用域实施基于作用域的访问控制。Scopes are used by the web API to implement scope-based access control. 例如,可以让 Web API 用户拥有读取和写入访问权限,或者只拥有读取访问权限。For example, users of the web API could have both read and write access, or users of the web API might have only read access. 若要在同一请求中获取多个权限,可在请求的单个 scope 参数中添加多个条目并用空格分隔。To acquire multiple permissions in the same request, you can add multiple entries in the single scope parameter of the request, separated by spaces.

以下示例显示了在 URL 中解码的作用域:The following example shows scopes decoded in a URL:

scope=https://contoso.partner.onmschina.cn/api/read openid offline_access

以下示例显示了在 URL 中编码的作用域:The following example shows scopes encoded in a URL:

scope=https%3A%2F%2Fcontoso.partner.onmschina.cn%2Fapi%2Fread%20openid%20offline_access

如果请求的作用域数超过为客户端应用程序授予的数目,则只有在授予至少一个权限的情况下,调用才会成功。If you request more scopes than what is granted for your client application, the call succeeds if at least one permission is granted. 生成的访问令牌的 scp 声明中只会填充已成功授予的权限。The scp claim in the resulting access token is populated with only the permissions that were successfully granted.

OpenID Connect 范围OpenID Connect scopes

OpenID Connect 标准指定了多个特殊的作用域值。The OpenID Connect standard specifies several special scope values. 以下作用域表示访问用户配置文件的权限:The following scopes represent the permission to access the user's profile:

  • openid - 请求 ID 令牌。openid - Requests an ID token.
  • offline_access - 使用 授权代码流请求刷新令牌。offline_access - Requests a refresh token using Auth Code flows.
  • 00000000-0000-0000-0000-000000000000 - 使用客户端 ID 作为范围即表示应用需要可以针对你自己的服务或 Web API(由同一客户端 ID 表示)使用的访问令牌。00000000-0000-0000-0000-000000000000 - Using the client ID as the scope indicates that your app needs an access token that can be used against your own service or web API, represented by the same client ID.

如果 /authorize 请求中的 response_type 参数包含 token,那么 scope 参数必须包含至少一个将被授予的资源作用域(除 openidoffline_access 以外)。If the response_type parameter in an /authorize request includes token, the scope parameter must include at least one resource scope other than openid and offline_access that will be granted. 否则,/authorize 请求会失败。Otherwise, the /authorize request fails.

请求令牌Request a token

若要请求访问令牌,需要一个授权代码。To request an access token, you need an authorization code. 下面是对 /authorize 终结点发出的授权代码请求的示例。Below is an example of a request to the /authorize endpoint for an authorization code. 不支持将自定义域与访问令牌一起使用。Custom domains are not supported for use with access tokens. 使用请求 URL 中的 tenant-name.partner.onmschina.cn 域。Use your tenant-name.partner.onmschina.cn domain in the request URL.

在以下示例中,会替换这些值:In the following example, you replace these values:

  • <tenant-name> - Azure AD B2C 租户的名称。<tenant-name> - The name of your Azure AD B2C tenant.
  • <policy-name> - 自定义策略或用户流的名称。<policy-name> - The name of your custom policy or user flow.
  • <application-ID> - 注册用于支持用户流的 Web 应用程序的应用程序标识符。<application-ID> - The application identifier of the web application that you registered to support the user flow.
  • <redirect-uri> - 注册客户端应用程序时输入的重定向 URI。<redirect-uri> - The Redirect URI that you entered when you registered the client application.
GET https://<tenant-name>.b2clogin.cn/<tenant-name>.partner.onmschina.cn/<policy-name>/oauth2/v2.0/authorize?
client_id=<application-ID>
&nonce=anyRandomValue
&redirect_uri=https://jwt.ms
&scope=https://<tenant-name>.partner.onmschina.cn/api/read
&response_type=code

包含授权代码的响应应类似于以下示例:The response with the authorization code should be similar to this example:

https://jwt.ms/?code=eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMC...

成功接收授权代码以后,可以将其用于请求访问令牌:After successfully receiving the authorization code, you can use it to request an access token:

POST <tenant-name>.partner.onmschina.cn/<policy-name>/oauth2/v2.0/token HTTP/1.1
Host: <tenant-name>.b2clogin.cn
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=<application-ID>
&scope=https://<tenant-name>.partner.onmschina.cn/api/read
&code=eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMC...
&redirect_uri=https://jwt.ms
&client_secret=2hMG2-_:y12n10vwH...

看到的内容应该类似于以下响应:You should see something similar to the following response:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrN...",
    "token_type": "Bearer",
    "not_before": 1549647431,
    "expires_in": 3600,
    "expires_on": 1549651031,
    "resource": "f2a76e08-93f2-4350-833c-965c02483b11",
    "profile_info": "eyJ2ZXIiOiIxLjAiLCJ0aWQiOiJjNjRhNGY3ZC0zMDkxLTRjNzMtYTcyMi1hM2YwNjk0Z..."
}

使用 https://jwt.ms 检查返回的访问令牌时,看到的内容应该类似于以下示例:When using https://jwt.ms to examine the access token that was returned, you should see something similar to the following example:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dl..."
}.{
  "iss": "https://contoso0926tenant.b2clogin.cn/c64a4f7d-3091-4c73-a7.../v2.0/",
  "exp": 1549651031,
  "nbf": 1549647431,
  "aud": "f2a76e08-93f2-4350-833c-965...",
  "oid": "1558f87f-452b-4757-bcd1-883...",
  "sub": "1558f87f-452b-4757-bcd1-883...",
  "name": "David",
  "tfp": "B2C_1_signupsignin1",
  "nonce": "anyRandomValue",
  "scp": "read",
  "azp": "38307aee-303c-4fff-8087-d8d2...",
  "ver": "1.0",
  "iat": 1549647431
}.[Signature]

后续步骤Next steps