Azure AD B2C自定义策略:如何向SPA返回自定义错误引导登录
解决方案推荐
方案一:在B2C策略中通过自定义页面触发定向跳转
在注册流程获取到用户注册状态声明后,添加分支逻辑:若用户已完成注册,直接通过自定义页面脚本跳转到应用的登录入口,并携带必要参数(如邮箱)。
- 添加编排步骤分支
在现有注册流程的步骤2之后,加入以下编排步骤:
<!-- 判断是否继续注册流程 --> <OrchestrationStep Order="3" Type="Choose"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>isRegistrationCompleted</Value> <Value>true</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="ProceedRegistration" TechnicalProfileReferenceId="YourExistingNextRegistrationStep" /> </ClaimsExchanges> </OrchestrationStep> <!-- 已完成注册则跳转到应用登录页 --> <OrchestrationStep Order="4" Type="Choose"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="false"> <Value>isRegistrationCompleted</Value> <Value>true</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="RedirectToLogin" TechnicalProfileReferenceId="RedirectToAppLogin" /> </ClaimsExchanges> </OrchestrationStep>
- 定义重定向用的技术配置文件
创建一个无需用户输入、自动跳转的技术配置文件:
<TechnicalProfile Id="RedirectToAppLogin"> <DisplayName>Redirect to App Login Page</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> <Item Key="ShowCancelButton">false</Item> <Item Key="ShowContinueButton">false</Item> <Item Key="SuppressClaimsExchange">true</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="email" /> </InputClaims> <DisplayClaims> <DisplayClaim ClaimTypeReferenceId="dummy" DisplayControlReferenceId="AutoRedirectControl" /> </DisplayClaims> </TechnicalProfile> <DisplayControl Id="AutoRedirectControl" UserInterfaceControlType="Custom"> <Metadata> <Item Key="HtmlContent"> <![CDATA[ <script> // 跳转到应用登录页,携带邮箱作为登录提示 const email = encodeURIComponent('{Claim:email}'); window.location.href = 'https://your-spa-app.com/login?login_hint=' + email; </script> ]]> </Item> </Metadata> </DisplayControl>
方案二:应用端前置判断用户状态
将判断逻辑移到SPA应用侧,在启动注册流程前先查询用户的注册完成状态,再决定启动注册或登录流程:
- 解析邀请链接中的token
// 处理邀请链接的逻辑 const handleInviteLink = async () => { const urlParams = new URLSearchParams(window.location.search); const inviteToken = urlParams.get('token'); // 解码token获取用户objectId和邮箱 const decodedToken = jwtDecode(inviteToken); const objectId = decodedToken.objectId; const userEmail = decodedToken.email; // 调用B2C用户信息端点获取注册状态(或用应用权限调用Graph API) const userInfoResp = await fetch(`https://your-b2c-tenant.b2clogin.com/your-tenant-id/your-profile-policy/openid/v2.0/userinfo`, { headers: { 'Authorization': `Bearer ${inviteToken}` } }); const userInfo = await userInfoResp.json(); if (userInfo.isRegistrationCompleted) { // 已完成注册,跳转登录页并携带登录提示 window.location.href = `/login?login_hint=${encodeURIComponent(userEmail)}`; } else { // 未完成注册,启动注册流程 window.location.href = `/register?token=${inviteToken}`; } };
方案三:利用B2C验证规则触发自定义重定向
通过验证技术配置文件判断注册状态,若已完成则返回自定义重定向响应:
- 创建验证技术配置文件
<TechnicalProfile Id="CheckRegistrationStatus"> <DisplayName>Check if user is registered</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <InputClaims> <InputClaim ClaimTypeReferenceId="isRegistrationCompleted" /> <InputClaim ClaimTypeReferenceId="email" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="redirectUri" /> </OutputClaims> <ClaimsTransformations> <ClaimsTransformation Id="SetRedirectUriForLogin" TransformationMethod="FormatStringClaim"> <InputClaims> <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="inputClaim" /> </InputClaims> <InputParameters> <InputParameter Id="stringFormat" Value="https://your-spa-app.com/login?login_hint={0}" /> </InputParameters> <OutputClaims> <OutputClaim ClaimTypeReferenceId="redirectUri" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation> </ClaimsTransformations> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile>
- 在编排步骤中添加验证
<OrchestrationStep Order="3" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="false"> <Value>isRegistrationCompleted</Value> <Value>true</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="RedirectToLogin" TechnicalProfileReferenceId="CheckRegistrationStatus" /> </ClaimsExchanges> </OrchestrationStep> <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="RedirectUri" />
内容的提问来源于stack exchange,提问作者WojBronx
相关产品推荐
相关产品推荐

