你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在 Azure Active Directory B2C 自定义策略中定义 RESTful 技术配置文件
注意
在 Azure Active Directory B2C 中,自定义策略主要用于解决复杂的情况。 在大多数情况下,建议你使用内置用户流。 如果尚未这样做,请从 Active Directory B2C 中的自定义策略入门了解自定义策略新手包。
Azure Active Directory B2C (Azure AD B2C) 为集成你自己的 RESTful 服务提供支持。 Azure AD B2C 在输入声明集合中将数据发送到 RESTful 服务,在输出声明集合中接收返回的数据。 有关详细信息,请参阅在 Azure AD B2C 自定义策略中集成 REST API 声明交换。
协议
“Protocol”元素的“Name”属性必须设置为 Proprietary
。 handler 属性必须包含 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,而 surname 作为 lastName 发送。 email 声明的设置保留原样。
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" />
<InputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName" />
<InputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName" />
</InputClaims>
InputClaimsTransformations 元素可以包含用于修改输入声明,或者先生成新输入声明,再将其发送到 REST API 的 InputClaimsTransformation 元素集合。
发送 JSON 有效负载
使用 REST API 技术配置文件可以将复杂的 JSON 有效负载发送到终结点。
发送复杂的 JSON 有效负载:
- 生成具备 GenerateJson 声明转换的 JSON 有效负载。
- 在 REST API 技术配置文件中执行以下操作:
- 添加具有对
GenerateJson
声明转换的引用的输入声明转换。 - 将
SendClaimsIn
元数据选项设置为body
- 将
ClaimUsedForRequestPayload
元数据选项设置为包含 JSON 有效负载的声明名称。 - 在输入声明中,添加对包含 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 中定义的名称。 如果设置了 DefaultValue
属性,则还可以包含 REST API 未返回的声明。
OutputClaimsTransformations 元素可能包含用于修改输出声明或生成新输出声明的 OutputClaimsTransformation 元素集合。
以下示例演示 REST API 返回的声明:
- 映射到 loyaltyNumber 声明名称的 MembershipId 声明。
技术配置文件还会返回标识提供者不返回的声明:
- 默认值设置为
true
的 loyaltyNumberIsNew 声明。
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="loyaltyNumber" PartnerClaimType="MembershipId" />
<OutputClaim ClaimTypeReferenceId="loyaltyNumberIsNew" DefaultValue="true" />
</OutputClaims>
Metadata
Attribute | 必须 | 说明 |
---|---|---|
ServiceUrl | 是 | REST API 终结点的 URL。 |
AuthenticationType | 是 | RESTful 声明提供程序所执行的身份验证类型。 可能的值:None 、Basic 、Bearer 、ClientCertificate 或 ApiKeyHeader 。
|
AllowInsecureAuthInProduction | 否 | 指示是否可以在生产环境中将 AuthenticationType 设置为 none (将 TrustFrameworkPolicy 的 DeploymentMode 设为 Production 或未指定)。 可能的值:true 或 false(默认值)。 |
SendClaimsIn | 否 | 指定如何将输入声明发送到 RESTful 声明提供程序。 可能的值:Body (默认值)、Form 、Header 、Url 或 QueryString 。 Body 值是在请求正文中以 JSON 格式发送的输入声明。 Form 值是在请求正文中以“&”分隔键值格式发送的输入声明。 Header 值是在请求标头中发送的输入声明。 Url 值是在 URL 中发送的输入声明,例如 https://api.example.com/{claim1}/{claim2}?{claim3}={claim4} 。 URL 的主机名部分不能包含声明。 QueryString 值是在请求查询字符串中发送的输入声明。 每个输入声明调用的 HTTP 谓词如下所示:
|
ClaimsFormat | 否 | 当前未使用,可以忽略。 |
ClaimUsedForRequestPayload | 否 | 包含要发送到 REST API 的有效负载的字符串声明名称。 |
DebugMode | 否 | 在调试模式下运行技术配置文件。 可能的值:true 或 false (默认值)。 在调试模式下,REST API 可以返回更多信息。 请参阅返回错误消息部分。 |
IncludeClaimResolvingInClaimsHandling | 否 | 对于输入和输出声明,指定声明解析是否包含在技术配置文件中。 可能的值:true 或 false (默认值)。 若要使用技术配置文件中的声明解析程序,请将此项设为 true 。 |
ResolveJsonPathsInJsonTokens | 否 | 指示技术配置文件是否解析 JSON 路径。 可能的值:true 或 false (默认值)。 使用此元数据从嵌套 JSON 元素中读取数据。 在 OutputClaim 中,将 PartnerClaimType 设为要输出的 JSON 路径元素。 例如:firstName.localized 或 data[0].to[0].email 。 |
UseClaimAsBearerToken | 否 | 包含持有者令牌的声明的名称。 |
错误处理。
以下元数据可用于配置 REST API 失败时显示的错误消息。 可以将错误消息本地化。
Attribute | 必须 | 说明 |
---|---|---|
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.azurewebsites.NET/api/identity/signup</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="SendClaimsIn">Body</Item>
</Metadata>
</TechnicalProfile>
如果身份验证类型设置为 Basic
,则 CryptographicKeys 元素包含以下属性:
属性 | 必须 | 说明 |
---|---|---|
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.azurewebsites.NET/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 元素包含以下属性:
属性 | 必须 | 说明 |
---|---|---|
ClientCertificate | 是 | 用于身份验证的 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.azurewebsites.NET/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 元素包含以下属性:
属性 | 必须 | 说明 |
---|---|---|
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.azurewebsites.NET/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 元素包含以下属性:
属性 | 必须 | 说明 |
---|---|---|
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.azurewebsites.NET/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"
}
属性 | 必须 | 说明 |
---|---|---|
版本 | 是 | REST API 版本。 例如:1.0.1 |
状态 | 是 | HTTP 响应状态代码类似数字,并且必须为 409。 REST 服务可以返回 HTTP 4XX 状态代码,但在 JSON 格式的响应正文中提交的值 status 必须是 409 。 |
code | 否 | 来自 RESTful 终结点提供程序的错误代码,启用 DebugMode 后会显示。 |
requestId | 否 | 来自 RESTful 终结点提供程序的请求标识符,启用 DebugMode 后会显示。 |
userMessage | 是 | 向用户显示的错误消息。 |
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; }
}
后续步骤
有关使用 RESTful 技术配置文件的示例,请参阅以下文章: