我正在尝试为 Azure AD B2C 实施密码更改自定义策略。
我使用this文件作为基础,更改了tenantid,并将其上传到Azure。
当我从 Azure 门户尝试演示时,它要求我登录,然后要求输入旧密码和新密码来更改密码。它工作得很好。我可以在那里更改我的密码。
然后我实现了一个按钮,重定向到密码更改 URL。
private redirectPasswordChange(appConfigService: AppConfigService): void {
const passwordChangeUrl = `${appConfigService.config.AD_AUTHORITY_CHANGE}?client_id=${appConfigService.config.AD_CLIENT_ID}
&nonce=defaultNonce
&redirect_uri=${appConfigService.config.BASE_URL}
&scope=openid
&response_type=id_token`;
if (isPlatformBrowser(PLATFORM_ID)) {
window.location.href = passwordChangeUrl;
} else {
this.window.location.href = passwordChangeUrl;
}
}
我已从 URL 中删除了
prompt=login
,因为要重定向到密码更改 URL 的按钮位于我们网站的“我的个人资料”部分。所以用户已经登录了,我不希望他们再次登录。
然后我在我们的网站上测试了它,当我点击按钮时,它会将我重定向到密码更改页面,它要求我输入旧密码、新密码并确认密码,这对我来说非常完美。但问题是,它不接受我的旧密码,它说“请求中提供的用户名或密码无效”。
我在网上搜索过这个问题,包括StackOverflow,但我发现这个问题有很多不同的答案。其中一位是这么说的:
Its because these input claims are overwriting the input claim names for login-noninteractive.
<InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="client_credentials" />
<InputClaim ClaimTypeReferenceId="scope" DefaultValue="https://{{tenantID}}.onmicrosoft.com/{{registeredApiAppName}}/.default" />
</InputClaims>
use different claim names, and use a partnerclaimtype to send the value with the original claim name.
https://stackoverflow.com/a/65931145/8831824
当我查看时,我可以看到PasswordChange.xml 上的那些编排步骤与TrustFrameworkBase.xml 中的相同
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
<ClaimsProviderSelections>
<ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
</ClaimsProviderSelections>
<ClaimsExchanges>
<ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
这里有某种覆盖吗?我的意思是,它们完全相同,但在两个不同的文件中,在 TrustFrameworkBase.xml 中,用于 SignUpOrSignIn 旅程,以及 PasswordChange.xml,用于 PasswordChange 旅程。
这是我的政策。我确实付出了很大的努力来解决这个问题,但我什至无法识别它。希望有人能给我一个想法来解决这个问题。感谢您的阅读。
TrustFrameworkBase.xml:https://pastebin.com/RXXhcwpN
TrustFrameworkExtensions.xml:https://pastebin.com/UUfVNaJ7
PasswordChange.xml:https://pastebin.com/sPjZjNYT
密码重置.xml:https://pastebin.com/CxE3pMH3
遇到了同样的问题,但与问题作者不同,我的问题不是将用户流与自定义策略混合在一起。
我 100% 确定根本原因不是
login-noninteractive
的错误配置,也不是 IdentityExperienceFramework
到 ProxyIdentityExperienceFrameworkAppId
的错误设置,因为我遵循了抄写本风格 ms 文档。
错误原因原来是 IdentityExperienceFramework 的清单文件中的属性 accessTokenAcceptedVersion 设置为
2
而不是 null
。
将其设置为
null
可以解决该问题。
很可能是因为我创建的应用程序最初配置为 支持任何组织目录中的帐户(任何 Azure AD 目录 - 多租户)但我改变了主意并将其更新为 仅支持此组织目录中的帐户(您的租户 仅 - 单租户)将清单属性更改为如下所示:
"signInAudience": "AzureADMyOrg",
如文档所述:
如果signInAudience是azureADandPersonalMicrosoftAccount,则(accessTokenAcceptedVersion的)值必须为2。
通过使用 https://b2ciefsetupapp.azurewebsites.net/ 并比较每个应用程序的配置来自动化辅助 B2C 租户的环境配置。
我强烈建议您删除应用程序并依赖自动化工具。 (我已经吸取教训了)
根据我的示例,您的密码更改 xml 应该让基本策略节点引用信任框架扩展策略,而不是信任框架基本策略。
最终问题是因为信任框架基础文件仅包含登录非交互式技术配置文件的一部分。它在扩展文件中完成,因此您必须引用满足所有依赖关系的文件。