Azure B2C自定义重置密码策略

时间:2020-09-22 19:53:43

标签: azure-ad-b2c

我在B2C中有一些自定义策略正在运行,但是我并没有试图使“重置密码”生效。我遇到的问题之一是,我调用Restful API来检查提供的电子邮件地址是否是本地用户,或者我们是否正在从Microsoft AAD登录。这可以正常工作,因此如果用户是SSO用户,则通过Microsoft Organization Identity登录用户;如果不是SSO用户,则通过B2C在本地登录。

我的问题是我正在尝试使用重置密码进行类似操作。我使用以下技术资料来获取电子邮件地址

<TechnicalProfile Id="SelfAsserted-Signin-Email">
    <DisplayName>Local Account Signin</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
        <Item Key="DisplayName">Signin To Tax Systems</Item>
        <Item Key="setting.operatingMode">Email</Item>
        <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
    </Metadata>
    <IncludeInSso>false</IncludeInSso>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="signInName" />
    </InputClaims>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
    </OutputClaims>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>

获取电子邮件地址后,我们将调用rest api来检查电子邮件地址。此检查告诉我们该用户是联盟用户还是本地用户。如果他们是联盟用户,我想输入错误信息,因为他们无法通过B2C重置密码。

如果他们是本地用户,那么我们想输入重置密码。这是通过以下技术资料完成的。问题是他们必须再次输入电子邮件地址,我希望用先前获得的电子邮件地址预先填充该电子邮件地址。

<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
  <DisplayName>Reset password using email address</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
    <Item Key="ContentDefinitionReferenceId">api.localaccountpasswordreset</Item>
    <Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Your account has been locked. Contact your support person to unlock it, then try again.</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
  </CryptographicKeys>
  <IncludeInSso>false</IncludeInSso>
  <InputClaims>
      <InputClaim ClaimTypeReferenceId="signInName" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
    <OutputClaim ClaimTypeReferenceId="objectId" />
    <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
    <OutputClaim ClaimTypeReferenceId="authenticationSource" />

  </OutputClaims>
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress" />
  </ValidationTechnicalProfiles>
</TechnicalProfile>

有人知道我该怎么做吗?在元数据等方面,我似乎找不到关于api.localaccountpasswordreset的详细信息。

3 个答案:

答案 0 :(得分:0)

您需要添加以下内容:

<Metadata>
            <Item Key="IncludeClaimResolvingInClaimsHandling">True</Item>
</Metadata>
<InputClaims>
            <InputClaim ClaimTypeReferenceId="email" DefaultValue="{OAUTH-KV:email}" AlwaysUseDefaultValue="true"></InputClaim>
</InputClaims>

因此,您可以设置调用策略授权URL的电子邮件,并附加电子邮件查询参数(&email=someemail@somedomain.com)

答案 1 :(得分:0)

由于您在步骤1中获得了声明signInName中的电子邮件,因此在步骤2中,您可以按以下步骤预先填充电子邮件:

  <InputClaims>
      <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="email"/>
  </InputClaims>

要显示“电子邮件验证”按钮,您必须将email声明为readOnly。否则,AAD B2C会假设该字段已经过验证而预先填充该字段,并且仅在电子邮件地址更改时才显示“验证”按钮。

一个真正的解决方案是:

    <ClaimsSchema>
      <!-- Sample: Read only email address to present to the user-->
      <ClaimType Id="readonlyEmail">
        <DisplayName>E-mail Address</DisplayName>
        <DataType>string</DataType>
        <UserInputType>Readonly</UserInputType>
      </ClaimType>
    </ClaimsSchema>
<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
  <DisplayName>Reset password using email address</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
    <Item Key="ContentDefinitionReferenceId">api.localaccountpasswordreset</Item>
    <Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Your account has been locked. Contact your support person to unlock it, then try again.</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
  </CryptographicKeys>
  <IncludeInSso>false</IncludeInSso>
  <InputClaims>
      <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="readonlyEmail"/>
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="readonlyEmail" PartnerClaimType="Verified.Email" Required="true" />
    <OutputClaim ClaimTypeReferenceId="objectId" />
    <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
    <OutputClaim ClaimTypeReferenceId="authenticationSource" />
  </OutputClaims>
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress" />
  </ValidationTechnicalProfiles>
</TechnicalProfile>

您需要修改AAD-UserReadUsingEmailAddress,使其输入声明为

<InputClaims>
  <InputClaim ClaimTypeReferenceId="readonlyEmail" PartnerClaimType="signInNames.emailAddress" Required="true" />
</InputClaims>

我将复制整个技术资料,并给它一个经过修改的新ID。

并且应以相同的方式用email替换书中对readOnlyEmail的进一步引用。

答案 2 :(得分:0)

您能做到这一点吗?我为一位客户进行了类似的设置,并通过添加2个验证配置文件(https://docs.microsoft.com/en-us/azure/active-directory-b2c/validation-technical-profile)并更改了输入声明来解决此问题:

  1. 在您的SelfAsserted-Signin-Email技术配置文件中调用REST API作为验证技术配置文件(https://docs.microsoft.com/en-us/azure/active-directory-b2c/restful-technical-profile)以检查电子邮件地址,如果未联合电子邮件地址,则在屏幕上显示错误;
  2. 调用一个ClaimsTransformation验证技术配置文件(https://docs.microsoft.com/en-us/azure/active-directory-b2c/claims-transformation-technical-profile),该技术配置文件引用ClaimsTransformation来将signInName复制到电子邮件(https://docs.microsoft.com/en-us/azure/active-directory-b2c/general-transformations#copyclaim)中;
  3. 将您的LocalAccountDiscoveryUsingEmailAddress技术资料中的输入声明更改为电子邮件。

这提供了一个干净的用户界面-如果联盟了用户,则第一个表单上会显示一个错误,而第二个屏幕会使用默认声明预先填充电子邮件字段。