在 Azure Active Directory B2C 自定义策略中定义 RESTful 技术配置文件Define a RESTful technical profile in an Azure Active Directory B2C custom policy

Note

在 Azure Active Directory B2C 中,custom policies 主要用于解决复杂方案。In Azure Active Directory B2C, custom policies are designed primarily to address complex scenarios. 大多数情况下,建议使用内置的用户流For most scenarios, we recommend that you use built-in user flows.

Azure Active Directory (Azure AD) B2C 为你自己的 RESTful 服务提供支持。Azure Active Directory (Azure AD) B2C provides support for your own RESTful service. Azure AD B2C 在输入声明集合中将数据发送到 RESTful 服务,在输出声明集合中接收返回的数据。Azure AD B2C sends data to the RESTful service in an input claims collection and receives data back in an output claims collection. 使用 RESTful 服务集成,可以:With RESTful service integration, you can:

  • 验证用户输入数据 - 防止将格式不当的数据保存到 Azure AD B2C。Validate user input data - Prevents malformed data from persisting into Azure AD B2C. 如果用户提供的值无效,RESTful 服务会返回错误消息,指示用户提供有效条目。If the value from the user is not valid, your RESTful service returns an error message that instructs the user to provide an entry. 例如,可以验证用户提供的电子邮件地址是否在客户数据库中存在。For example, you can verify that the email address provided by the user exists in your customer's database.
  • 覆盖输入声明 - 可以重新设置输入声明中的值的格式。Overwrite input claims - Enables you to reformat values in input claims. 例如,如果用户使用全小写或全大写字母输入了名字,则你可以设置该名字的格式,只将第一个字母大写。For example, if a user enters the first name in all lowercase or all uppercase letters, you can format the name with only the first letter capitalized.
  • 丰富用户数据 - 可以进一步与企业业务线应用程序集成。Enrich user data - Enables you to further integrate with corporate line-of-business applications. 例如,RESTful 服务可以接收用户的电子邮件地址、查询客户的数据库,并向 Azure AD B2C 返回用户的会员号。For example, your RESTful service can receive the user's email address, query the customer's database, and return the user's loyalty number to Azure AD B2C. 返回声明可存储、可在后续的业务流程步骤中进行评估,或包含在访问令牌中。The return claims can be stored, evaluated in the next Orchestration Steps, or included in the access token.
  • 运行自定义业务逻辑 - 可以发送推送通知、更新企业数据库、运行用户迁移过程、管理权限、审核数据库,以及执行其他操作。Run custom business logic - Enables you to send push notifications, update corporate databases, run a user migration process, manage permissions, audit databases, and perform other actions.

策略可将输入声明发送到 REST API。Your policy may send input claims to your REST API. REST API 还可以返回稍后可在策略中使用的输出声明,或者引发错误消息。The REST API may also return output claims that you can use later in your policy, or it can throw an error message. 可通过以下方式来设计与 RESTful 服务的集成:You can design the integration with the RESTful services in the following ways:

  • 验证技术配置文件 - 验证技术配置文件调用 RESTful 服务。Validation technical profile - A validation technical profile calls the RESTful service. 在用户旅程继续执行之前,验证技术配置文件将验证用户提供的数据。The validation technical profile validates the user-provided data before the user journey continues. 使用验证技术配置文件时,错误消息将显示在自我断言的页面上,并在输出声明中返回。With the validation technical profile, an error message is display on a self-asserted page and returned in output claims.
  • 声明交换 - 通过业务流程步骤调用 RESTful 服务。Claims exchange - A call is made to the RESTful service through an orchestration step. 在此方案中,不会在任何用户界面中呈现错误消息。In this scenario, there is no user-interface to render the error message. 如果 REST API 返回错误,则将用户重定向回到信赖方应用程序并显示错误消息。If your REST API returns an error, the user is redirected back to the relying party application with the error message.

协议Protocol

“Protocol”元素的“Name”属性必须设置为 ProprietaryThe Name attribute of the Protocol element needs to be set to Proprietary. handler 属性必须包含 Azure AD B2C 使用的协议处理程序程序集的完全限定名称:Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullThe handler attribute must contain the fully qualified name of the protocol handler assembly that is used by Azure AD B2C: Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.

以下示例演示了一个 RESTful 技术配置文件:The following example shows a RESTful technical profile:

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

输入声明Input claims

InputClaims 元素包含要发送到 REST API 的声明列表。The InputClaims element contains a list of claims to send to the REST API. 还可将声明名称映射到 REST API 中定义的名称。You can also map the name of your claim to the name defined in the REST API. 以下示例演示策略与 REST API 之间的映射。Following example shows the mapping between your policy and the REST API. givenName 声明作为 firstName 发送到 REST API,而 surname 作为 lastName 发送。The givenName claim is sent to the REST API as firstName, while surname is sent as lastName. email 声明的设置保留原样。The email claim is set as is.

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

InputClaimsTransformations 元素可以包含用于修改输入声明,或者先生成新输入声明,再将其发送到 REST API 的 InputClaimsTransformation 元素集合。The InputClaimsTransformations element may contain a collection of InputClaimsTransformation elements that are used to modify the input claims or generate new ones before sending to the REST API.

输出声明Output claims

OutputClaims 元素包含 REST API 返回的声明列表。The OutputClaims element contains a list of claims returned by the REST API. 可能需要将策略中定义的声明名称映射到 REST API 中定义的名称。You may need to map the name of the claim defined in your policy to the name defined in the REST API. 如果设置了 DefaultValue 属性,则还可以包含 REST API 标识提供者不会返回的声明。You can also include claims that aren't returned by the REST API identity provider, as long as you set the DefaultValue attribute.

OutputClaimsTransformations 元素可能包含用于修改输出声明或生成新输出声明的 OutputClaimsTransformation 元素集合。The OutputClaimsTransformations element may contain a collection of OutputClaimsTransformation elements that are used to modify the output claims or generate new ones.

以下示例演示 REST API 返回的声明:The following example shows the claim returned by the REST API:

  • 映射到 loyaltyNumber 声明名称的 MembershipId 声明。The MembershipId claim that is mapped to the loyaltyNumber claim name.

技术配置文件还会返回标识提供者不返回的声明:The technical profile also returns claims, that aren't returned by the identity provider:

  • 默认值设置为 trueloyaltyNumberIsNew 声明。The loyaltyNumberIsNew claim that has a default value set to true.
<OutputClaims>
  <OutputClaim ClaimTypeReferenceId="loyaltyNumber" PartnerClaimType="MembershipId" />
  <OutputClaim ClaimTypeReferenceId="loyaltyNumberIsNew" DefaultValue="true" />
</OutputClaims>

MetadataMetadata

属性Attribute 必须Required 说明Description
ServiceUrlServiceUrl Yes REST API 终结点的 URL。The URL of the REST API endpoint.
AuthenticationTypeAuthenticationType Yes RESTful 声明提供程序所执行的身份验证类型。The type of authentication being performed by the RESTful claims provider. 可能的值:NoneBasicClientCertificatePossible values: None, Basic, or ClientCertificate. None 值表示 REST API 不是匿名的。The None value indicates that the REST API is not anonymous. Basic 值表示使用 HTTP 基本身份验证保护 REST API。The Basic value indicates that the REST API is secured with HTTP basic authentication. 只有经验证的用户(包括 Azure AD B2C)可以访问你的 API。Only verified users, including Azure AD B2C, can access your API. ClientCertificate(建议)值表示 REST API 使用客户端证书身份验证来限制访问。The ClientCertificate (recommended) value indicates that the REST API restricts access using client certificate authentication. 只有包含相应证书的服务(例如 Azure AD B2C)能够访问你的服务。Only services that have the appropriate certificates, such as Azure AD B2C can access your service.
SendClaimsInSendClaimsIn No 指定如何将输入声明发送到 RESTful 声明提供程序。Specifies how the input claims are sent to the RESTful claims provider. 可能的值:Body(默认值)、FormHeaderQueryStringPossible values: Body (default), Form, Header, or QueryString. Body 值是在请求正文中以 JSON 格式发送的输入声明。The Body value is the input claim that is sent in the request body in JSON format. Form 值是在请求正文中以“&”分隔键值格式发送的输入声明。The Form value is the input claim that is sent in the request body in an ampersand '&' separated key value format. Header 值是在请求标头中发送的输入声明。The Header value is the input claim that is sent in the request header. QueryString 值是在请求查询字符串中发送的输入声明。The QueryString value is the input claim that is sent in the request query string.
ClaimsFormatClaimsFormat No 指定输出声明的格式。Specifies the format for the output claims. 可能的值:Body(默认值)、FormHeaderQueryStringPossible values: Body (default), Form, Header, or QueryString. Body 值是在请求正文中以 JSON 格式发送的输出声明。The Body value is the output claim that is sent in the request body in JSON format. Form 值是在请求正文中以“&”分隔键值格式发送的输出声明。The Form value is the output claim that is sent in the request body in an ampersand '&' separated key value format. Header 值是在请求标头中发送的输出声明。The Header value is the output claim that is sent in the request header. QueryString 值是在请求查询字符串中发送的输出声明。The QueryString value is the output claim that is sent in the request query string.
DebugModeDebugMode No 在调试模式下运行技术配置文件。Runs the technical profile in debug mode. 在调试模式下,REST API 可以返回更多信息。In debug mode, the REST API can return more information. 请参阅“返回错误消息”部分。See the returning error message section.

加密密钥Cryptographic keys

如果身份验证类型设置为 None,则不使用 CryptographicKeys 元素。If the type of authentication is set to None, the CryptographicKeys element is not used.

<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 元素包含以下属性:If the type of authentication is set to Basic, the CryptographicKeys element contains the following attributes:

属性Attribute 必须Required 说明Description
BasicAuthenticationUsernameBasicAuthenticationUsername Yes 用于身份验证的用户名。The username that is used to authenticate.
BasicAuthenticationPasswordBasicAuthenticationPassword Yes 用于身份验证的密码。The password that is used to authenticate.

以下示例演示了使用基本身份验证的技术配置文件:The following example shows a technical profile with basic authentication:

<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 元素包含以下属性:If the type of authentication is set to ClientCertificate, the CryptographicKeys element contains the following attribute:

属性Attribute 必须Required 说明Description
ClientCertificateClientCertificate Yes 用于身份验证的 X509 证书(RSA 密钥集)。The X509 certificate (RSA key set) to use to authenticate.
<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>

返回错误消息Returning error message

REST API 可能需要返回错误消息,例如“在 CRM 系统中未找到该用户”。Your REST API may need to return an error message, such as 'The user was not found in the CRM system'. 发生错误时,REST API 应返回包含以下属性的 HTTP 409 错误消息(冲突响应状态代码):In an error occurs, the REST API should return an HTTP 409 error message (Conflict response status code) with following attributes:

属性Attribute 必须Required 说明Description
版本version Yes 1.0.01.0.0
状态status Yes 409409
codecode No 来自 RESTful 终结点提供程序的错误代码,启用 DebugMode 后会显示。An error code from the RESTful endpoint provider, which is displayed when DebugMode is enabled.
requestIdrequestId No 来自 RESTful 终结点提供程序的请求标识符,启用 DebugMode 后会显示。A request identifier from the RESTful endpoint provider, which is displayed when DebugMode is enabled.
userMessageuserMessage Yes 向用户显示的错误消息。An error message that is shown to the user.
developerMessagedeveloperMessage No 问题的详细说明及其解决方法,启用 DebugMode 后会显示。The verbose description of the problem and how to fix it, which is displayed when DebugMode is enabled.
moreInfomoreInfo No 指向其他信息的 URI,启用 DebugMode 后会显示。A URI that points to additional information, which is displayed when DebugMode is enabled.

以下示例演示了一个以 JSON 格式返回错误消息的 REST API:The following example shows a REST API that returns an error message formatted in 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" 
}

以下示例演示了一个返回错误消息的 C# 类:The following example shows a C# class that returns an error message:

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; }
}