gpt4 book ai didi

Azure AD B2C - 忘记密码用户旅程 - 不允许旧密码?

转载 作者:行者123 更新时间:2023-12-02 06:25:59 27 4
gpt4 key购买 nike

我正在基于自定义策略构建 Azure AD B2C 配置。登录、个人资料编辑、密码更改等已按预期工作。

但目前我正在努力解决密码忘记政策。我想实现新密码不等于旧密码。 Google 和 Microsoft 文档总是为我提供密码更改的示例。当我更改密码时,我必须输入旧密码和新密码。然后我就可以比较旧的和新的。例如像here描述的方式

但是,当用户忘记密码时,他当然无法输入旧密码与新密码进行比较。

有没有办法建立一个真正的密码忘记策略,而无需输入旧密码,但仍然确保新密码不等于旧密码?

提前致谢!

亚历克斯

最佳答案

我也遇到了同样的问题,Jas Suri 的回答对我帮助很大。然而,我在让它工作时遇到了一些问题。因此,这就是为什么我要分享我的最终解决方案,以防其他人面临同样的问题。

我使用以下内容作为基础:https://github.com/azure-ad-b2c/samples/tree/master/policies/password-reset-not-last-password/policy但做了一些调整。以下是我必须添加到现有政策中才能使其发挥作用的内容:

声明架构:

这些声明将在稍后使用。

    <ClaimsSchema>
<ClaimType Id="SamePassword">
<DisplayName>samePassword</DisplayName>
<DataType>boolean</DataType>
<UserHelpText />
</ClaimType>
<ClaimType Id="resetPasswordObjectId">
<DisplayName>User's Object ID</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="oid" />
<Protocol Name="OpenIdConnect" PartnerClaimType="oid" />
<Protocol Name="SAML2" PartnerClaimType="http://schemas.microsoft.com/identity/claims/objectidentifier" />
</DefaultPartnerClaimTypes>
<UserHelpText>Object identifier (ID) of the user object in Azure AD.</UserHelpText>
</ClaimType>
</ClaimsSchema>

声明转换:

第一个声明转换检查是否设置了resetPasswordObjectId,如果没有设置,则之前使用新密码尝试登录显然不起作用,因此newPassword不一样作为旧/当前密码。第二个声明转换检查声明 SamePassword 是否等于 false。如果不是,则会抛出错误并显示“您无法使用旧密码”。稍后将详细介绍这一点。

 <ClaimsTransformations>
<ClaimsTransformation Id="CheckPasswordEquivalence" TransformationMethod="DoesClaimExist">
<InputClaims>
<InputClaim ClaimTypeReferenceId="resetPasswordObjectId" TransformationClaimType="inputClaim" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="SamePassword" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="AssertSamePasswordIsFalse" TransformationMethod="AssertBooleanClaimIsEqualToValue">
<InputClaims>
<InputClaim ClaimTypeReferenceId="SamePassword" TransformationClaimType="inputClaim" />
</InputClaims>
<InputParameters>
<InputParameter Id="valueToCompareTo" DataType="boolean" Value="false" />
</InputParameters>
</ClaimsTransformation>
</ClaimsTransformations>

ClaimsProvider:

总体思路是使用新输入的密码并尝试登录用户。如果登录成功,新密码与旧/当前密码相同,并且不允许。登录时,我们创建一个输出声明并将其称为 resetPasswordObjectId,它要么未设置,要么等于登录用户的对象 ID。然后,我们检查resetPasswordObjectId是否存在(在声明转换部分完成),如果不存在,则可以使用newPassword,因为它与旧/当前密码不同。

要在用户输入旧密码时显示正确的错误消息,我们需要覆盖 <LocalizedResources Id="api.localaccountpasswordreset.en"> 中 TrustFrameworkLocalization.xml 中的 UserMessageIfClaimsTransformationBooleanValueIsNotEqual像这样<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">You must not use your old password.</LocalizedString> .

使用下面的声明提供程序时,请确保替换所有标有 TODO 的部分。

   <ClaimsProviders>
<ClaimsProvider>
<DisplayName>Password Reset without same password</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="login-NonInteractive-PasswordChange">
<DisplayName>Local Account SignIn</DisplayName>
<Protocol Name="OpenIdConnect" />
<Metadata>
<Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item>
<Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item>
<Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item>
<Item Key="ProviderName">https://sts.windows.net/</Item>
<!-- TODO replace YOUR-TENANT-ID -->
<Item Key="METADATA">https://login.microsoftonline.com/YOUR-TENANT.onmicrosoft.com/.well-known/openid-configuration</Item>
<!-- TODO replace YOUR-TENANT-ID -->
<Item Key="authorization_endpoint">https://login.microsoftonline.com/YOUR-TENANT.onmicrosoft.com/oauth2/token</Item>
<Item Key="response_types">id_token</Item>
<Item Key="response_mode">query</Item>
<Item Key="scope">email openid</Item>
<!-- TODO ensure this line is commented out-->
<!-- <Item Key="grant_type">password</Item> -->
<Item Key="UsePolicyInRedirectUri">false</Item>
<Item Key="HttpBinding">POST</Item>
<!-- TODO -->
<!-- ProxyIdentityExperienceFramework application / client id -->
<Item Key="client_id">YOUR-PROXY-CLIENT-ID</Item>
<!-- Native App -->
<!-- TODO -->
<!-- IdentityExperienceFramework application / client id -->
<Item Key="IdTokenAudience">YOUR-IDENTITY-CLIENT-ID</Item>
<!-- Web Api -->
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username" Required="true" />
<!-- INFO: replaced oldPassword with newPassword, that way we try logging in with the new password. If the login is successful, we know the newPassword is the same as the old / current password-->
<InputClaim ClaimTypeReferenceId="newPassword" PartnerClaimType="password" Required="true" />
<InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" />
<InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" />
<InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
<!-- TODO -->
<!-- ProxyIdentityExperienceFramework application / client id -->
<InputClaim ClaimTypeReferenceId="client_id" DefaultValue="YOUR-PROXY-CLIENT-ID" />
<!-- TODO -->
<!-- IdentityExperienceFramework application / client id -->
<InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="YOUR-IDENTITY-CLIENT-ID" />
</InputClaims>
<OutputClaims>
<!-- INFO: assign the objectId (oid) to resetPasswordObjectId, since the claim objectId might already be set. In that case there would be no way of knowing whether it was set due to the attempted login with the newPassword-->
<OutputClaim ClaimTypeReferenceId="resetPasswordObjectId" PartnerClaimType="oid" />
<OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
</OutputClaims>
</TechnicalProfile>
<!--Logic to check new password is not the same as old password
Validates old password before writing new password-->
<TechnicalProfile Id="LocalAccountWritePasswordUsingObjectId">
<DisplayName>Reset password</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.localaccountpasswordreset</Item>
<!-- set in the TrustFrameworkLocalization.xml -->
<!-- <Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">You must not use your old password.</Item> -->
</Metadata>
<CryptographicKeys>
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
</CryptographicKeys>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
<OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="login-NonInteractive-PasswordChange" ContinueOnError="true" />
<ValidationTechnicalProfile ReferenceId="ComparePasswords" />
<ValidationTechnicalProfile ReferenceId="AAD-UserWritePasswordUsingObjectId">
<Preconditions>
<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
<Value>SamePassword</Value>
<Value>True</Value>
<Action>SkipThisValidationTechnicalProfile</Action>
</Precondition>
</Preconditions>
</ValidationTechnicalProfile>
</ValidationTechnicalProfiles>
</TechnicalProfile>
<!-- Runs claimsTransformations to make sure new and old passwords differ -->
<TechnicalProfile Id="ComparePasswords">
<DisplayName>Compare Email And Verify Email</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="SamePassword" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CheckPasswordEquivalence" />
<OutputClaimsTransformation ReferenceId="AssertSamePasswordIsFalse" />
</OutputClaimsTransformations>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>

关于Azure AD B2C - 忘记密码用户旅程 - 不允许旧密码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66208105/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com