在 Azure Active Directory B2C 自定义策略中定义 RESTful 技术配置文件

重要

自 2025 年 5 月 1 日起,Azure AD B2C 将不再可供新客户购买。 在我们的常见问题解答中了解详细信息

备注

在 Azure Active Directory B2C 中,自定义策略 主要用于解决复杂场景。 对于大多数场景,我们建议您使用内置的用户流。 如果未这样做,请通过 Active Directory B2C 中的自定义策略入门来了解自定义策略初学者包。

Azure Active Directory B2C (Azure AD B2C) 支持集成自己的 RESTful 服务。 Azure AD B2C 将数据发送到输入声明集合中的 RESTful 服务,并在输出声明集合中接收数据。

协议

“Protocol”元素的“Name”属性必须设置为 处理程序属性必须包含 Azure AD B2C 使用的协议处理程序程序集的完全限定名称: Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

以下示例显示了 RESTful 技术配置文件:

<TechnicalProfile Id="REST-UserMembershipValidator">
  <DisplayName>Validate user input data and return loyaltyNumber claim</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  ...

输入声明

InputClaims 元素包含要发送到 REST API 的声明列表。 还可以将声明的名称映射到 REST API 中定义的名称。 以下示例显示了策略与 REST API 之间的映射。 givenName 声明作为 firstName 发送到 REST API,而姓氏作为 lastName 发送。 电子邮件声明按原样设置。

<InputClaims>
  <InputClaim ClaimTypeReferenceId="email" />
  <InputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName" />
  <InputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName" />
</InputClaims>

InputClaimsTransformations 元素可能包含 InputClaimsTransformation 元素的集合,这些元素用于在发送到 REST API 之前修改输入声明或生成新元素。

发送 JSON 有效负载

REST API 技术配置文件允许将复杂的 JSON 有效负载发送到终结点。

发送复杂的 JSON 有效负载:

  1. 使用 GenerateJson 声明转换生成 JSON 有效负载。
  2. 在 REST API 技术配置文件中:
    1. 添加具有对声明转换的引用的 GenerateJson 输入声明转换。
    2. SendClaimsIn 元数据选项设置为 body
    3. ClaimUsedForRequestPayload 元数据选项设置为包含 JSON 有效负载的声明的名称。
    4. 在输入声明中,添加对包含 JSON 有效负载的输入声明的引用。

以下示例 TechnicalProfile 使用第三方电子邮件服务(在本例中为 SendGrid)发送验证电子邮件。

<TechnicalProfile Id="SendGrid">
  <DisplayName>Use SendGrid's email API to send the code to the user</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://api.sendgrid.com/v3/mail/send</Item>
    <Item Key="AuthenticationType">Bearer</Item>
    <Item Key="SendClaimsIn">Body</Item>
    <Item Key="ClaimUsedForRequestPayload">sendGridReqBody</Item>
    <Item Key="DefaultUserMessageIfRequestFailed">Cannot process your request right now, please try again later.</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="BearerAuthenticationToken" StorageReferenceId="B2C_1A_SendGridApiKey" />
  </CryptographicKeys>
  <InputClaimsTransformations>
    <InputClaimsTransformation ReferenceId="GenerateSendGridRequestBody" />
  </InputClaimsTransformations>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="sendGridReqBody" />
  </InputClaims>
</TechnicalProfile>

输出声明

OutputClaims 元素包含 REST API 返回的声明列表。 可能需要将策略中定义的声明的名称映射到 REST API 中定义的名称。 还可以包含 REST API 不返回的声明,只要设置 DefaultValue 属性。

OutputClaimsTransformations 元素可能包含用于修改输出声明或生成新输出声明的 OutputClaimsTransformation 元素集合。

以下示例演示 REST API 返回的声明:

  • 映射到 loyaltyNumber 声明名称的 MembershipId 声明。

技术配置文件还返回标识提供者未返回的声明:

  • 将默认值设置为true 声明。
<OutputClaims>
  <OutputClaim ClaimTypeReferenceId="loyaltyNumber" PartnerClaimType="MembershipId" />
  <OutputClaim ClaimTypeReferenceId="loyaltyNumberIsNew" DefaultValue="true" />
</OutputClaims>

元数据

特征 必选 DESCRIPTION
ServiceUrl 是的 REST API 终结点的 URL。
身份验证类型 是的 RESTful 声明提供程序执行的身份验证类型。 可能的值:None、、BasicBearerClientCertificateApiKeyHeader
  • 该值 None 指示 REST API 是匿名的。
  • 该值 Basic 指示 REST API 使用 HTTP 基本身份验证进行保护。 只有已验证的用户(包括 Azure AD B2C)才能访问 API。
  • ClientCertificate 指示 REST API 使用客户端证书身份验证限制访问。 只有具有相应证书的服务(例如 Azure AD B2C)才能访问 API。
  • 该值 Bearer 指示 REST API 使用客户端 OAuth2 持有者令牌限制访问。
  • 该值 ApiKeyHeader 指示 REST API 使用 API 密钥 HTTP 标头(如 x-functions-key)进行保护。
AllowInsecureAuthInProduction 指示是否可以AuthenticationType在生产环境中将它设置为 noneDeploymentModeTrustFrameworkPolicy 设置为Production或未指定)。 可能的值:true 或 false(默认值)。
SendClaimsIn 指定如何将输入声明发送到 RESTful 声明提供程序。 可能的值: Body (默认值)、FormHeaderUrlQueryString
该值 Body 是以 JSON 格式的请求正文发送的输入声明。
该值 Form 是在请求正文中以“&”分隔的键值格式发送的输入声明。
该值 Header 是在请求标头中发送的输入声明。
该值 Url 是在 URL 中发送的输入声明,例如 https://api.example.com/{claim1}/{claim2}?{claim3}={claim4}。 URL 的主机名部分不能包含声明。
该值 QueryString 是在请求查询字符串中发送的输入声明。
每个谓词调用的 HTTP 谓词如下所示:
  • Body:发布
  • Form:发布
  • Header:获取
  • Url:获取
  • QueryString:获取
ClaimsFormat 当前未使用,可以忽略。
ClaimUsedForRequestPayload 包含要发送到 REST API 的有效负载的字符串声明的名称。
DebugMode 在调试模式下运行技术配置文件。 可能的值:truefalse(默认值)。 在调试模式下,REST API 可以返回更多信息。 请参阅 “返回错误消息 ”部分。
IncludeClaimResolvingInClaimsHandling 对于输入和输出声明,指定声明解析是否包含在技术配置文件中。 可能的值:truefalse(默认值)。 若要使用技术配置文件中的声明解析程序,请将此项设为 true
ResolveJsonPathsInJsonTokens 指示技术配置文件是否解析 JSON 路径。 可能的值:truefalse(默认值)。 使用此元数据从嵌套 JSON 元素读取数据。 在 OutputClaimPartnerClaimType ,设置要输出的 JSON 路径元素。 例如:firstName.localizeddata[0].to[0].email
UseClaimAsBearerToken 包含持有者令牌的声明的名称。

错误处理

以下元数据可用于配置 REST API 失败时显示的错误消息。 可以将错误消息本地化

特征 必选 DESCRIPTION
DefaultUserMessageIfRequestFailed 所有 REST API 异常的默认自定义错误消息。
UserMessageIfCircuitOpen 无法访问 REST API 时出现错误消息。 如果未指定,则返回 DefaultUserMessageIfRequestFailed。
UserMessageIfDnsResolutionFailed DNS 解析异常的错误消息。 如果未指定,则返回 DefaultUserMessageIfRequestFailed。
UserMessageIfRequestTimeout 连接超时时出现错误消息。如果未指定,则返回 DefaultUserMessageIfRequestFailed。

加密密钥

如果身份验证类型设置为 None,则不使用 CryptographicKeys 元素。

<TechnicalProfile Id="REST-API-SignUp">
  <DisplayName>Validate user's input data and return loyaltyNumber claim</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://your-app-name.chinacloudsites.cn/api/identity/signup</Item>
    <Item Key="AuthenticationType">None</Item>
    <Item Key="SendClaimsIn">Body</Item>
  </Metadata>
</TechnicalProfile>

如果身份验证类型设置为 Basic则 CryptographicKeys 元素包含以下属性:

特征 必选 DESCRIPTION
BasicAuthenticationUsername 是的 用于进行身份验证的用户名。
BasicAuthenticationPassword 是的 用于进行身份验证的密码。

以下示例显示了具有基本身份验证的技术配置文件:

<TechnicalProfile Id="REST-API-SignUp">
  <DisplayName>Validate user's input data and return loyaltyNumber claim</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://your-app-name.chinacloudsites.cn/api/identity/signup</Item>
    <Item Key="AuthenticationType">Basic</Item>
    <Item Key="SendClaimsIn">Body</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_B2cRestClientId" />
    <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_B2cRestClientSecret" />
  </CryptographicKeys>
</TechnicalProfile>

如果身份验证类型设置为 ClientCertificate则 CryptographicKeys 元素包含以下属性:

特征 必选 DESCRIPTION
客户端证书 是的 用于进行身份验证的 X509 证书(RSA 密钥集)。
<TechnicalProfile Id="REST-API-SignUp">
  <DisplayName>Validate user's input data and return loyaltyNumber claim</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://your-app-name.chinacloudsites.cn/api/identity/signup</Item>
    <Item Key="AuthenticationType">ClientCertificate</Item>
    <Item Key="SendClaimsIn">Body</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="ClientCertificate" StorageReferenceId="B2C_1A_B2cRestClientCertificate" />
  </CryptographicKeys>
</TechnicalProfile>

如果身份验证类型设置为 Bearer则 CryptographicKeys 元素包含以下属性:

特征 必选 DESCRIPTION
BearerAuthenticationToken OAuth 2.0 持有者令牌。
<TechnicalProfile Id="REST-API-SignUp">
  <DisplayName>Validate user's input data and return loyaltyNumber claim</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://your-app-name.chinacloudsites.cn/api/identity/signup</Item>
    <Item Key="AuthenticationType">Bearer</Item>
    <Item Key="SendClaimsIn">Body</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="BearerAuthenticationToken" StorageReferenceId="B2C_1A_B2cRestClientAccessToken" />
  </CryptographicKeys>
</TechnicalProfile>

如果身份验证类型设置为 ApiKeyHeader则 CryptographicKeys 元素包含以下属性:

特征 必选 DESCRIPTION
HTTP 标头的名称,例如 x-functions-key, 或 x-api-key 是的 用于进行身份验证的密钥。

备注

目前,Azure AD B2C 仅支持一个 HTTP 标头进行身份验证。 如果 RESTful 调用需要多个标头(例如客户端 ID 和客户端机密值),则需要以某种方式代理请求。

<TechnicalProfile Id="REST-API-SignUp">
  <DisplayName>Validate user's input data and return loyaltyNumber claim</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://your-app-name.chinacloudsites.cn/api/identity/signup</Item>
    <Item Key="AuthenticationType">ApiKeyHeader</Item>
    <Item Key="SendClaimsIn">Body</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="x-functions-key" StorageReferenceId="B2C_1A_RestApiKey" />
  </CryptographicKeys>
</TechnicalProfile>

返回验证错误消息

REST API 可能需要返回错误消息,例如“在 CRM 系统中找不到用户”。 如果发生错误,REST API 应返回 HTTP 4xx 错误消息,例如 400(错误请求)或 409(冲突)响应状态代码。 响应正文包含 JSON 格式的错误消息:

{
  "version": "1.0.0",
  "status": 409,
  "code": "API12345",
  "requestId": "50f0bd91-2ff4-4b8f-828f-00f170519ddb",
  "userMessage": "Message for the user",
  "developerMessage": "Verbose description of problem and how to fix it.",
  "moreInfo": "https://restapi/error/API12345/moreinfo"
}
特征 必选 DESCRIPTION
版本 是的 REST API 版本。 例如:1.0.1
地位 是的 HTTP 响应状态代码类似数字,并且必须为 409。 REST 服务可以返回 HTTP 4XX 状态代码,但在 JSON 格式的响应正文中提交的值 status 必须是 409
代码 RESTful 终结点提供程序的错误代码,该提供程序在启用时 DebugMode 显示。
requestId RESTful 终结点提供程序的请求标识符,启用时 DebugMode 会显示该标识符。
用户消息 是的 向用户显示的错误消息。
developerMessage 问题的详细说明以及如何修复该问题,该说明在启用时 DebugMode 显示。
moreInfo 指向其他信息的 URI,该信息在启用时 DebugMode 显示。

以下示例演示返回错误消息的 C# 类:

public class ResponseContent
{
  public string Version { get; set; }
  public int Status { get; set; }
  public string Code { get; set; }
  public string UserMessage { get; set; }
  public string DeveloperMessage { get; set; }
  public string RequestId { get; set; }
  public string MoreInfo { get; set; }
}