你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Azure Active Directory B2C 中设置 OAuth 2.0 客户端凭据流

开始之前,可使用“选择策略类型”选择器来选择要设置的策略类型。 Azure Active Directory B2C 提供了两种定义用户如何与应用程序交互的方法:通过预定义的用户流,或者通过可完全配置的自定义策略。 对于每种方法,本文中所需的步骤都不同。

OAuth 2.0 客户端凭据授予流允许应用(机密客户端)在调用 Web 资源(例如 REST API)时使用其自己的凭据(而不是模拟用户)进行身份验证。 这种授予通常用于必须在后台运行的服务器间交互,不需要立即与用户交互。 此类应用程序通常称为守护程序或服务帐户。

在客户端凭据流中,由管理员向应用程序本身直接授予权限。 当应用向资源出示令牌时,资源强制应用本身具有执行操作的授权,因为没有用户参与身份验证。 本文介绍授权应用程序调用 API 所需的步骤,以及如何获取调用该 API 所需的令牌。

此功能目前提供公共预览版。

应用注册概述

若要让应用能够使用客户端机密登录,然后调用 Web API,你需要在 Azure AD B2C 目录中注册两个应用程序。

  • 应用程序注册能让你的应用使用 Azure AD B2C 登录。 此应用注册过程会生成应用程序 ID(也称为“客户端 ID”),将其作为该应用的唯一标识。 你还将创建一个客户端密码,你的应用可使用该密码安全地获取令牌。

  • Web API 注册可使应用调用安全的 Web API。 注册内容包括 Web API 的作用域。 作用域提供了一种方法来管理受保护资源(例如你的 Web API)的访问权限。 然后,你可以向 Web API 范围授予应用程序权限。 在请求访问令牌时,你的应用需要指定请求的 .default 范围参数。 Azure AD B2C 返回授予应用的 Web API 范围。

下图演示了应用体系结构和注册:

Diagram of a web app with web A P I call registrations and tokens.

步骤 1:注册 Web API 应用

在此步骤中,将 Web API(应用 2)注册到其范围。 稍后,授予应用程序(应用 1)对这些范围的权限。 如果已有此类应用注册,请跳过此步骤,然后转到下一步:步骤 1.1 定义 Web API 角色(范围)

请按照以下步骤创建 Web API 应用注册(应用 ID: 2):

  1. 登录 Azure 门户

  2. 确保正在使用的目录包含 Azure AD B2C 租户。 在门户工具栏中选择“目录 + 订阅”图标。

  3. 在“门户设置 | 目录+订阅”页上的“目录名称”列表中找到你的 Azure AD B2C 目录,然后选择“切换”。

  4. 在 Azure 门户中,搜索并选择“Azure AD B2C”。

  5. 选择“应用注册”,然后选择“新建注册” 。

  6. 对于名称,请输入应用程序的名称(例如 my-api1) 。 保留“重定向 URI”和“支持的帐户类型”的默认值。

  7. 选择“注册”。

  8. 完成应用注册后,选择“概述”。

  9. 记录“应用程序(客户端) ID”值,以便在稍后配置 Web 应用程序时使用。

    Screenshot that demonstrates how to get a web A P I application I D.

步骤 1.1 定义 Web API 角色(范围)

在此步骤中,将配置 Web API“应用程序 ID URI”,然后定义“应用角色”。 应用角色由 OAuth 2.0 范围使用并在代表你的 API 的应用程序注册上定义。 你的应用程序使用具有 .default 范围的应用程序 ID URI。 若要定义应用角色,请执行以下步骤:

  1. 选择创建的 Web API,例如 my-api1。

  2. 在“管理”下,选择“公开 API” 。

  3. 选择“应用程序 ID URI”旁边的“设置”链接。 将默认值 (GUID) 替换为一个唯一名称(例如 api),然后选择“保存”。

  4. 复制应用程序 ID URI。 以下屏幕截图显示了如何复制应用程序 ID URI。

    Screenshot shows how to copy the application I D.

  5. 在“管理”下,选择“清单”以打开应用程序清单编辑器。 在编辑器中,找到 appRoles 设置,并定义面向 applications 的应用角色。 每个应用角色定义都必须为其 id 值提供一个全局唯一标识符 (GUID)。 通过在 Microsoft PowerShell 中运行 new-guid 命令或在线 GUID 生成器来生成新的 GUID。 每个应用角色定义的 value 属性都会出现在范围内,即 scp 声明中。 value 属性不能包含空格。 以下示例演示了两个应用角色:读取和写入。

    "appRoles": [
    {
      "allowedMemberTypes": ["Application"],
      "displayName": "Read",
      "id": "d6a15e20-f83c-4264-8e61-5082688e14c8",
      "isEnabled": true,
      "description": "Readers have the ability to read tasks.",
      "value": "app.read"
    },
    {
      "allowedMemberTypes": ["Application"],
      "displayName": "Write",
      "id": "204dc4ab-51e1-439f-8c7f-31a1ebf3c7b9",
      "isEnabled": true,
      "description": "Writers have the ability to create tasks.",
      "value": "app.write"
    }],
    
  6. 在页面顶部,选择“保存”以保存清单更改。

步骤 2:注册应用程序

要使应用能够使用客户端凭据流通过 Azure AD B2C 登录,可以使用现有的应用程序,或注册一个新应用程序(应用 1)。

如果使用现有应用,请确保该应用的 accessTokenAcceptedVersion 设置为 2

  1. 在 Azure 门户中,搜索并选择“Azure AD B2C”。
  2. 选择“应用注册”,然后从列表中选择现有应用
  3. 在左侧菜单中的“管理”下,选择“清单”打开清单编辑器。
  4. 找到 accessTokenAcceptedVersion 元素,将其值设置为 2
  5. 在页面顶部,选择“保存”以保存更改。

若要创建新的 Web 应用注册,请执行以下步骤:

  1. 在 Azure 门户中,搜索并选择“Azure AD B2C”

  2. 选择“应用注册”,然后选择“新建注册” 。

  3. 输入应用程序的“名称”。 例如,ClientCredentials_app。

  4. 保留其他值不变,然后选择“注册”。

  5. 记录“应用程序(客户端) ID”,以便在后续步骤中使用。

    Screenshot shows how to get the application I D.

步骤 2.1 创建客户端机密

为注册的应用创建客户端机密。 你的应用在请求令牌时使用客户端机密来证明其标识。

  1. 在“管理”下选择“证书和密码”。

  2. 选择“新建客户端机密”。

  3. 在“说明”框中输入客户端机密的说明(例如 clientsecret1)。

  4. 在“过期时间”下,选择机密持续生效的时间,然后选择“添加”。

  5. 记下机密的“值”。 将该值用于后面的一个步骤中的配置。

    Screenshot shows how to copy the application secret.

步骤 2.2 为 Web API 授予应用权限

若要向应用(应用 1)授予权限,请执行以下步骤:

  1. 选择“应用注册”,然后选择你创建的应用(应用 1)。

  2. 在“管理”下选择“API 权限”。

  3. 在“已配置权限”下,选择“添加权限”。

  4. 选择“我的 API”选项卡。

  5. 选择应授予 Web 应用程序访问权限的 API(应用 2)。 例如,输入“my-api1”。

  6. 选择“应用程序权限”。

  7. 在“权限”下,展开“应用”,然后选择之前定义的范围(例如,app.read 和 app.write)。

    Screenshot shows how to grant the application A P I permissions.

  8. 选择“添加权限”。

  9. 选择“向<租户名称>授予管理员许可”。

  10. 选择 “是”

  11. 选择“刷新”,然后验证两个范围的“状态”下是否均显示“已授予...” 。

步骤 3:获取访问令牌

用户流或自定义策略无需执行启用客户端凭据的特定操作。 Azure AD B2C 用户流和自定义策略都支持客户端凭据流。 如果你尚未这样做,请创建用户流或自定义策略。 然后,使用偏好的 API 开发应用程序生成授权请求。 使用以下信息作为 POST 请求的正文,构造一个与此示例类似的调用:

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/<policy>/oauth2/v2.0/token

  • <tenant-name> 替换为你的 Azure AD B2C 租户名称。 例如,contoso.b2clogin.com
  • <policy> 替换为用户流或自定义策略的完整名称。 请注意,所有类型的用户流和自定义策略都支持客户端凭据流。 可以使用你拥有的任何用户流或自定义策略,或创建新的用户流或自定义策略,例如注册或登录。
密钥
grant_type client_credentials
client_id 步骤 2 注册应用程序中的客户端 ID。
client_secret 步骤 2.1 创建客户端机密中的客户端机密值。
scope 步骤 1.1 定义 Web API 角色(范围).default 中的应用程序 ID URI。 例如 https://contoso.onmicrosoft.com/api/.defaulthttps://contoso.onmicrosoft.com/12345678-0000-0000-0000-000000000000/.default

实际的 POST 请求如以下示例所示:

请求

POST /<tenant-name>.onmicrosoft.com/B2C_1A_SUSI/oauth2/v2.0/token HTTP/1.1
Host: <tenant-name>.b2clogin.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=33333333-0000-0000-0000-000000000000
&client_secret=FyX7Q~DuPJ...
&scope=https%3A%2F%2Fcontoso.onmicrosoft.com%2Fapi%2F.default

响应:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlBFcG5OZDlnUkNWWUc2dUs...",
    "token_type": "Bearer",
    "not_before": 1645172292,
    "expires_in": 3600,
    "expires_on": 1645175892,
    "resource": "33333333-0000-0000-0000-000000000000"
}

了解返回访问令牌声明。 下表列出了与客户端凭据流相关的声明。

声明 说明
aud 标识令牌的目标接收方。 API 的客户端 ID。
sub 与发起请求的应用程序关联的服务主体。 它是授权请求的 client_id 的服务主体。
azp 被授权方 - 向其颁发访问令牌的一方。 发起请求的应用程序的客户端 ID。 它与你在授权请求的 client_id 中指定的值相同。
scp 应用程序 API 公开的范围集(空格分隔符)。 在客户端凭据流中,授权请求要求提供 .default 范围,而令牌包含 API 公开(并由应用管理员同意)的范围列表。 例如,app.read app.write

步骤 3.1 使用脚本获取访问令牌

使用以下 PowerShell 脚本测试配置:

$appId = "<client ID>"
$secret = "<client secret>"
$endpoint = "https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/<policy>/oauth2/v2.0/token"
$scope = "<Your API id uri>/.default"
$body = "grant_type=client_credentials&scope=" + $scope + "&client_id=" + $appId + "&client_secret=" + $secret

$token = Invoke-RestMethod -Method Post -Uri $endpoint -Body $body

使用以下 cURL 脚本测试配置:

curl --location --request POST 'https://<your-tenant>.b2clogin.com/<your-tenant>.onmicrosoft.com/<policy>/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--form 'grant_type="client_credentials"' \
--form 'client_id="<client ID>"' \
--form 'client_secret="<client secret>"' \
--form 'scope="<Your API id uri>/.default"'

步骤 4:自定义令牌

此功能仅适用于自定义策略。 对于设置步骤,请在前面的选择器中选择“自定义策略”。

自定义策略提供了一种扩展令牌颁发过程的方法。 若要自定义 OAuth 2.0 客户端凭据的用户旅程,请按照指导如何配置客户端凭据用户旅程操作。 然后,在 JwtIssuer 技术配置文件中,添加 ClientCredentialsUserJourneyId 元数据以及对你创建的用户旅程的引用。

以下示例演示如何将 ClientCredentialsUserJourneyId 添加到令牌颁发者技术配置文件。

<TechnicalProfile Id="JwtIssuer">
  <Metadata>
    <Item Key="ClientCredentialsUserJourneyId">ClientCredentialsJourney</Item>
  </Metadata>
</TechnicalProfile>

以下示例演示客户端凭据用户旅程。 需要第一个和最后一个业务流程步骤。

<UserJourneys>
  <UserJourney Id="ClientCredentialsJourney">
    <OrchestrationSteps>
      <!-- [Required] Do the client credentials -->
      <OrchestrationStep Order="1" Type="ClaimsExchange">
        <ClaimsExchanges>
          <ClaimsExchange Id="ClientCredSetupExchange" TechnicalProfileReferenceId="ClientCredentials_Setup" />
        </ClaimsExchanges>
      </OrchestrationStep>

      <!-- [Optional] Call a REST API or claims transformation -->
      <OrchestrationStep Order="2" Type="ClaimsExchange">
        <ClaimsExchanges>
          <ClaimsExchange Id="TokenAugmentation" TechnicalProfileReferenceId="TokenAugmentation" />
        </ClaimsExchanges>
      </OrchestrationStep>

      <!-- [Required] Issue the access token -->
      <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
    </OrchestrationSteps>
  </UserJourney>
</UserJourneys>

后续步骤

了解如何在 Azure AD B2C 中配置资源所有者密码凭据流