Azure B2C自定义策略:通过扩展属性获取用户实际登录用户名
问题描述
我已实现通过扩展属性(用于MFA的extension_mfaEmail)查询用户。部分用户以用户名作为主身份登录,部分以邮箱登录。我需要将实际登录用户名作为输出声明,但调用技术配置文件AAD-UserReadUsingMFAEmailAddress后,signinName声明返回的是内部用户主体名称{guid}@{tenant}.onmicrosoft.com,并非所需的实际登录用户名。
请问:
- 如何判断用户使用的登录方式(邮箱/用户名)?
- 无论哪种登录方式,如何获取实际登录用户名?
- 为何该技术配置文件不识别
SigninNames.username?
相关技术配置文件代码
<TechnicalProfile Id="AAD-UserReadUsingMFAEmailAddress"> <Metadata> <Item Key="Operation">Read</Item> <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item> </Metadata> <IncludeInSso>false</IncludeInSso> <InputClaims> <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="extension_mfaEmail" /> </InputClaims> <OutputClaims> <!-- Required claims --> <OutputClaim ClaimTypeReferenceId="objectId" /> <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" /> <OutputClaim ClaimTypeReferenceId="userPrincipalName" /> <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" /> <OutputClaim ClaimTypeReferenceId="signInName" /> <!-- HOW DO I READ USERNAME --> </OutputClaims> <OutputClaimsTransformations> <OutputClaimsTransformation ReferenceId="AssertAccountEnabledIsTrue" /> </OutputClaimsTransformations> <IncludeTechnicalProfile ReferenceId="AAD-Common" /> </TechnicalProfile>
解答
1. 判断用户登录方式(邮箱/用户名)
- 先在技术配置文件的
OutputClaims中添加signInNames.userName输出声明,确保能获取到用户名类型的登录名:<OutputClaim ClaimTypeReferenceId="signInNames.userName" /> - 创建声明转换,通过判断
signInNames.emailAddress和signInNames.userName的存在性确定登录方式:<ClaimsTransformation Id="DetermineSignInMethod" TransformationMethod="SwitchCase"> <InputClaims> <InputClaim ClaimTypeReferenceId="signInNames.emailAddress" TransformationClaimType="inputClaim" /> </InputClaims> <InputParameters> <InputParameter Id="defaultCase" DataType="string" Value="username" /> <InputParameter Id="case1" DataType="string" Value="email" /> <InputParameter Id="case1Value" DataType="string" Value="{signInNames.emailAddress}" /> </InputParameters> <OutputClaims> <OutputClaim ClaimTypeReferenceId="signInMethod" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation> - 在技术配置文件的
OutputClaimsTransformations中引用该转换,之后signInMethod声明会返回email或username标识登录方式。
2. 获取实际登录用户名
- 确保
OutputClaims中同时包含邮箱和用户名的登录声明:<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" /> <OutputClaim ClaimTypeReferenceId="signInNames.userName" /> - 添加声明转换,优先取用户名,无值则取邮箱,生成实际登录用户名:
<ClaimsTransformation Id="GetActualSignInName" TransformationMethod="GetFirstNonEmptyClaim"> <InputClaims> <InputClaim ClaimTypeReferenceId="signInNames.userName" /> <InputClaim ClaimTypeReferenceId="signInNames.emailAddress" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="actualSignInName" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation> - 在技术配置文件的
OutputClaimsTransformations中引用该转换,最终通过actualSignInName声明获取用户实际使用的登录名。
3. 为何技术配置文件不识别SigninNames.username
- 命名错误:AAD本地账户的用户名对应的正确PartnerClaimType是
signInNames.userName(注意大小写,是userName而非username),你使用的SigninNames.username大小写和名称都不符合AAD的属性命名规范,因此无法识别。 - 未声明输出:默认的
AAD-UserReadUsingMFAEmailAddress技术配置文件没有包含该声明的输出项,需要手动在OutputClaims中添加对应的OutputClaim,才能从AAD获取并返回该值。
内容的提问来源于stack exchange,提问作者Erkan Y.
相关产品推荐
相关产品推荐

