如何在基于邮箱的2FA自定义策略中用Mail覆盖signInName?
Azure AD B2C 邮箱2FA:无法将Mail字段复制到readOnlyEmail声明
基于微软的邮箱/电话MFA示例策略实现邮箱2FA时,需要用AD用户的Mail字段替代SignInName填充readOnlyEmail声明,用于后续的邮箱验证步骤。
已完成操作
- 编排步骤3通过
AAD-UserReadUsingObjectId技术配置文件成功从AD拉取到Mail属性:
<OrchestrationStep Order="3" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimEquals" ExecuteActionsIf="true"> <Value>authenticationSource</Value> <Value>socialIdpAuthentication</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions> <ClaimsExchanges> <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> </ClaimsExchanges> </OrchestrationStep>
- 添加编排步骤4,尝试将
Mail复制到readOnlyEmail:
<OrchestrationStep Order="4" Type="ClaimsExchange"> <ClaimsExchanges> <ClaimsExchange Id="AADCopyMailToReadOnlyEmail" TechnicalProfileReferenceId="TpCopyMailToReadOnlyEmail" /> </ClaimsExchanges> </OrchestrationStep>
对应的技术配置文件和声明转换:
<TechnicalProfile Id="TpCopyMailToReadOnlyEmail"> <DisplayName>Copy the Mail attribute to the ReadOnlyEmail attribute.</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <InputClaims> <InputClaim ClaimTypeReferenceId="mail" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="mail" /> </OutputClaims> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="CopyMailToReadOnlyEmail" /> </OutputClaimsTransformations> </TechnicalProfile>
<ClaimsTransformation Id="CopyMailToReadOnlyEmail" TransformationMethod="FormatStringClaim"> <InputClaims> <InputClaim ClaimTypeReferenceId="mail" TransformationClaimType="inputClaim" /> </InputClaims> <InputParameters> <InputParameter Id="stringFormat" DataType="string" Value="{0}" /> </InputParameters> <OutputClaims> <OutputClaim ClaimTypeReferenceId="readOnlyEmail" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation>
问题
执行EmailVerifyOnSignIn技术配置文件时,readOnlyEmail声明仍保留SignInName的值,未被Mail字段覆盖。
原因分析
- 技术配置文件Handler选择错误:使用
SelfAssertedAttributeProvider作为Handler,该Provider用于需要用户交互的场景(比如收集用户输入),不适合无交互的声明复制操作,会导致声明转换无法正确执行。 - 声明转换方法冗余:使用
FormatStringClaim进行简单的字段复制,不如直接使用CopyClaim方法高效且不易出错。 - 步骤顺序问题:如果原示例中存在其他设置
readOnlyEmail的步骤(比如第一步将SignInName复制到readOnlyEmail),若当前复制步骤在其之前,会被后续步骤覆盖。
修复方案
1. 修改技术配置文件Handler
将技术配置文件的Handler替换为ClaimsTransformationProvider,专门用于无交互的声明转换:
<TechnicalProfile Id="TpCopyMailToReadOnlyEmail"> <DisplayName>Copy Mail to ReadOnlyEmail</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <InputClaims> <InputClaim ClaimTypeReferenceId="mail" /> </InputClaims> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="CopyMailToReadOnlyEmail" /> </OutputClaimsTransformations> </TechnicalProfile>
2. 简化声明转换方法
使用CopyClaim直接复制字段,替代冗余的FormatStringClaim:
<ClaimsTransformation Id="CopyMailToReadOnlyEmail" TransformationMethod="CopyClaim"> <InputClaims> <InputClaim ClaimTypeReferenceId="mail" TransformationClaimType="inputClaim" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="readOnlyEmail" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation>
3. 确认编排步骤顺序
确保步骤4(复制Mail到readOnlyEmail)在所有可能设置readOnlyEmail的步骤之后执行,避免被覆盖。比如原示例中第一步复制SignInName到readOnlyEmail,则步骤4需要在该步骤之后。
内容的提问来源于stack exchange,提问作者bperniciaro
相关产品推荐
相关产品推荐

