Azure B2C技术配置文件中,REST API报错时如何回滚用户创建?
问题背景
在Azure AD B2C的LocalAccountSignUpWithLogonEmail自我断言技术配置文件中,注册流程会先执行AAD-UserWriteUsingLogonEmail创建B2C用户,再调用REST - SingupComplete接口将B2C Object ID关联至数据库用户配置文件。当REST API调用失败时,需要回滚已创建的B2C用户,但现有尝试的方法均未奏效:
- 直接在REST API中调用Graph删除用户时,返回“用户未找到”错误,推测B2C用户尚未持久化到存储;
- 配置
ContinueOnError后通过额外技术配置文件删除用户,无法向前端返回错误提示。
可行解决方案
方案1:调整流程顺序避免回滚
将操作顺序反转,先完成数据库关联,再创建B2C用户:
- 先通过自我断言技术配置文件收集所有用户注册信息;
- 调用REST API在数据库中创建用户占位记录,获取数据库用户ID;
- 调用
AAD-UserWriteUsingLogonEmail创建B2C用户,同时将数据库用户ID存入B2C扩展属性; - 若B2C用户创建失败,调用另一个REST API删除数据库中的占位记录。
此方案从根源上避免了回滚B2C用户的需求,无需处理事务补偿。
方案2:利用B2C内置能力实现同步补偿
针对现有流程,通过以下配置实现REST失败时的B2C用户删除及错误提示:
步骤1:修改REST技术配置文件
开启ContinueOnError,并配置错误返回声明:
<TechnicalProfile Id="REST - SingupComplete"> <DisplayName>Signup Complete REST API</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-api-domain.com/signup-complete</Item> <Item Key="AuthenticationType">None</Item> <Item Key="SendClaimsIn">Body</Item> <Item Key="ContinueOnError">true</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="objectId" /> <InputClaim ClaimTypeReferenceId="email" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="rest_signup_error" DefaultValue="false" /> <OutputClaim ClaimTypeReferenceId="error_message" /> </OutputClaims> </TechnicalProfile>
注:REST API需在失败时将rest_signup_error设为true,并返回具体错误信息至error_message
步骤2:添加B2C用户删除技术配置文件
使用B2C内置的Azure AD操作处理器直接删除用户(无需依赖Graph API,无同步延迟):
<TechnicalProfile Id="AAD-DeleteUserOnRestFailure"> <DisplayName>Delete B2C User When REST Fails</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureActiveDirectoryProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <Metadata> <Item Key="Operation">Delete</Item> <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item> </Metadata> <InputClaims> <InputClaim ClaimTypeReferenceId="objectId" Required="true" /> </InputClaims> </TechnicalProfile>
步骤3:更新注册技术配置文件
添加删除用户的验证步骤,并配置错误提示:
<TechnicalProfile Id="LocalAccountSignUpWithLogonEmail"> <!-- 原有配置保持不变 --> <Metadata> <Item Key="IpAddressClaimReferenceId">IpAddress</Item> <Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item> <!-- 添加错误消息展示配置 --> <Item Key="UserMessageIfClaimsPrincipalInvalid">{error_message}</Item> </Metadata> <ValidationTechnicalProfiles> <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" /> <ValidationTechnicalProfile ReferenceId="REST - SingupComplete" /> <!-- 仅当REST失败时执行删除操作 --> <ValidationTechnicalProfile ReferenceId="AAD-DeleteUserOnRestFailure"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="false"> <Value>rest_signup_error</Value> <Value>true</Value> <Action>SkipThisValidationTechnicalProfile</Action> </Precondition> </Preconditions> </ValidationTechnicalProfile> </ValidationTechnicalProfiles> </TechnicalProfile>
方案3:异步补偿(适合高并发场景)
若同步补偿存在性能或延迟问题,可采用异步方案:
- 注册流程中,即使REST API失败,仍允许用户完成注册,但将B2C用户标记为“未激活”状态;
- 后台定时任务扫描“未激活”用户,调用Graph API删除B2C用户,并同步删除数据库关联记录;
- 用户下次登录时,提示注册未完成,引导重新注册。
对现有尝试的修正说明
- 关于Graph API删除用户失败:
AAD-UserWriteUsingLogonEmail执行后,用户已写入B2C本地存储,但Graph API存在同步延迟,导致即时调用找不到用户。改用B2C内置的AzureActiveDirectoryProvider处理器(如方案2中的删除技术配置文件)可直接操作本地存储,无延迟问题。 - 关于无法返回错误信息:通过在REST技术配置文件中返回
error_message声明,并在注册技术配置文件的Metadata中配置UserMessageIfClaimsPrincipalInvalid,即可将错误信息展示给前端用户。
内容的提问来源于stack exchange,提问作者SanAtSO
相关产品推荐
相关产品推荐

