基于Azure AD B2C实现并行REST API调用及多应用认证处理
处理多Web应用的Azure AD B2C自定义策略方案
核心思路
要实现单个自定义策略支持两个Web应用的认证请求,并根据请求来源触发对应(或并行)的API校验,需完成三个关键环节:识别应用来源、条件/并行API调用逻辑、多应用适配配置。
1. 识别应用来源
优先通过client_id(AD B2C注册的应用ID)识别应用,比自定义查询参数更安全;若需用查询参数,可通过声明转换捕获。
方式1:捕获client_id声明
AD B2C会自动将请求的client_id作为声明传入,直接使用即可:
<!-- 在需要判断的步骤中直接引用client_id声明 --> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>client_id</Value> <Value>你的应用A ClientID</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition>
方式2:捕获自定义查询参数
若需用自定义查询参数(如appSource),添加声明转换提取:
<ClaimsTransformation Id="GetAppSourceFromQuery" TransformationMethod="GetQueryParameter"> <InputParameters> <InputParameter Id="ParameterName" DataType="string" Value="appSource" /> <InputParameter Id="DefaultValue" DataType="string" Value="defaultApp" /> </InputParameters> <OutputClaims> <OutputClaim ClaimTypeReferenceId="appSource" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation>
在用户旅程的登录步骤后调用该转换,将appSource存入声明:
<OrchestrationStep Order="4" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="GetAppSource" TechnicalProfileReferenceId="SelfAsserted-GetAppSource" /> </ClaimsExchanges> </OrchestrationStep> <TechnicalProfile Id="SelfAsserted-GetAppSource"> <DisplayName>Get App Source</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <Metadata> <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item> </Metadata> <OutputClaims> <OutputClaim ClaimTypeReferenceId="appSource" /> </OutputClaims> <ClaimsTransformations> <ClaimsTransformationReference Id="GetAppSourceFromQuery" /> </ClaimsTransformations> </TechnicalProfile>
2. API调用逻辑实现
AD B2C自定义策略本身不支持原生并行API调用,可通过两种方式实现需求:
方案A:条件串行调用(按应用选择API)
根据应用来源声明,跳过不需要的API调用步骤,只执行对应应用的校验:
<!-- 应用A的API校验步骤 --> <OrchestrationStep Order="5" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="false"> <Value>client_id</Value> <Value>应用A ClientID</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="REST-ValidateUser-AppA" TechnicalProfileReferenceId="REST-ValidateUser-AppA" /> </ClaimsExchanges> </OrchestrationStep> <!-- 应用B的API校验步骤 --> <OrchestrationStep Order="6" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="false"> <Value>client_id</Value> <Value>应用B ClientID</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="REST-ValidateUser-AppB" TechnicalProfileReferenceId="REST-ValidateUser-AppB" /> </ClaimsExchanges> </OrchestrationStep>
其中API技术配置文件示例:
<TechnicalProfile Id="REST-ValidateUser-AppA"> <DisplayName>Validate User for App A</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://你的应用A校验API地址</Item> <Item Key="SendClaimsIn">Body</Item> <Item Key="AuthenticationType">None</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="email" /> <InputClaim ClaimTypeReferenceId="password" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="userValidated" /> </OutputClaims> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile>
方案B:中间API聚合并行调用
若需同时调用两个API,可搭建中间聚合API:由B2C调用中间API,中间API内部并行请求两个后端校验API,合并结果后返回给B2C。
<TechnicalProfile Id="REST-ValidateUser-Parallel"> <DisplayName>Parallel Validate 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地址</Item> <Item Key="SendClaimsIn">Body</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="email" /> <InputClaim ClaimTypeReferenceId="password" /> <InputClaim ClaimTypeReferenceId="client_id" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="userValidated" /> </OutputClaims> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile>
中间API内部可通过Task.WhenAll实现并行调用,例如:
public async Task<IActionResult> ValidateUser([FromBody] UserValidationRequest request) { var taskA = _httpClient.PostAsJsonAsync("https://appA-api.com/validate", request); var taskB = _httpClient.PostAsJsonAsync("https://appB-api.com/validate", request); await Task.WhenAll(taskA, taskB); var resultA = await taskA.Content.ReadFromJsonAsync<ValidationResult>(); var resultB = await taskB.Content.ReadFromJsonAsync<ValidationResult>(); return Ok(new { userValidated = resultA.IsValid && resultB.IsValid }); }
3. 多应用适配配置
确保两个Web应用在AD B2C中完成注册,并在自定义策略的RelyingParty节点关联:
<RelyingParty> <DefaultUserJourney ReferenceId="SignIn" /> <TechnicalProfile Id="PolicyProfile"> <DisplayName>PolicyProfile</DisplayName> <Protocol Name="OpenIdConnect" /> <OutputClaims> <OutputClaim ClaimTypeReferenceId="displayName" /> <OutputClaim ClaimTypeReferenceId="email" /> <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/> </OutputClaims> <SubjectNamingInfo ClaimType="sub" /> </TechnicalProfile> <ClientDefinitions> <ClientDefinition ClientId="应用A ClientID" UserJourneyReferenceId="SignIn" /> <ClientDefinition ClientId="应用B ClientID" UserJourneyReferenceId="SignIn" /> </ClientDefinitions> </RelyingParty>
关键技术要点
- 条件步骤执行:通过
Precondition元素支持ClaimEquals、ClaimExists等判断逻辑,实现步骤的条件跳过/执行。 - REST API集成:
RestfulProvider支持配置API地址、请求方式、输入输出声明,以及错误处理逻辑。 - 声明管理:AD B2C自动传递
client_id等核心请求参数,也可通过GetQueryParameter自定义提取查询参数。
内容的提问来源于stack exchange,提问作者CloudSpace03
相关产品推荐
相关产品推荐

