首次登录时重置密码期间发生Azure AD B2C错误(使用自定义策略) [英] Azure AD B2C errors during reset password at the first logon (using custom policies)

查看:27
本文介绍了首次登录时重置密码期间发生Azure AD B2C错误(使用自定义策略)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用the "reset password" repo中所述的自定义策略在首次登录(在Azure ADB2C中)后强制重置密码。

我正在使用自定义策略,在尝试上载";SignUpOrSignin.xml";自定义策略时出现验证错误。消息是:

找不到所需的关键字为";ApplicationObjectId";的元数据项 在带有ID的技术配置文件中 策略中的";AAD-UserRemoveMustResetPasswordUsingObjectId"; 租户";resetpasswordtest.onmicrosoft.com";

的B2C_1A_SIGNUP_SIGNIN&Quot;

以下是我遵循的步骤:

  1. 我从thisGitHub示例下载了自定义策略XMLs文件(如readme.md file末尾所述)
  2. 我替换了";您的tenant.onmicrosoft.com";和";Facebook客户端&qot;
  3. I";将";SignUpOrSignin.xml";和";TrustFrameworkExtensions.xml";与取自the "reset password" repo的文件合并。
  4. 我创建了扩展属性(使用Azure门户)
  5. 我使用图形工具创建了一个用户(因此,我100%确定该用户是以安全的方式创建的,并且具有正确的扩展属性)
  6. 最后我(按顺序)将以下XMLs上传到门户:

TrustFrameworkBase.xml

TrustFrameworkExtensions.xml

PasswordReset.xml

ProfileEdit.xml

SignUpOrSignin.xml

尝试上载最后一个(SignUpOrSignin.xml)时出现问题 这里出了什么问题?Here您可以找到前面5个XML文件的完整实现。

请查看我粘贴了";TrustFrameworkExtensions.xml";和";SignUpOrSignin.xml";自定义策略的以下部分。

感谢阅读

<TrustFrameworkPolicy 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" 
  PolicySchemaVersion="0.3.0.0" 
  TenantId="resetpasswordtest.onmicrosoft.com" 
  PolicyId="B2C_1A_TrustFrameworkExtensions" 
  PublicPolicyUri="http://resetpasswordtest.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">
  
  <BasePolicy>
    <TenantId>resetpasswordtest.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
  </BasePolicy>
  <BuildingBlocks>
  <ClaimsSchema>
    <!--Demo: Specifies whether user must reset the password-->
    <ClaimType Id="extension_mustResetPassword">
        <DisplayName>Must reset password</DisplayName>
        <DataType>boolean</DataType>
        <UserHelpText>Specifies whether user must reset the password</UserHelpText>
      </ClaimType>
  </ClaimsSchema>
  </BuildingBlocks>

  <ClaimsProviders>
   <ClaimsProvider>
      <DisplayName>Azure Active Directory</DisplayName>
      <TechnicalProfiles>  

        <TechnicalProfile Id="AAD-UserReadUsingObjectId">
          <OutputClaims>
            <!--Demo: Read the 'must reset password' extension attribute -->
            <OutputClaim ClaimTypeReferenceId="extension_mustResetPassword" />
          </OutputClaims>
        </TechnicalProfile>

        <TechnicalProfile Id="AAD-UserRemoveMustResetPasswordUsingObjectId">
          <Metadata>
            <Item Key="Operation">DeleteClaims</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
          </InputClaims>
          <PersistedClaims>
            <PersistedClaim ClaimTypeReferenceId="objectId" />
            <PersistedClaim ClaimTypeReferenceId="extension_mustResetPassword" />            
          </PersistedClaims>
          <IncludeTechnicalProfile ReferenceId="AAD-Common" />
        </TechnicalProfile>

        <!--Demo: to create the extension attribute extension_mustResetPassword, you should upload the policy 
            and create one account. Then ***comment out this technical profile***.
            -->
        <TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
          <PersistedClaims>
            <PersistedClaim ClaimTypeReferenceId="extension_mustResetPassword" DefaultValue="true" />
          </PersistedClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

    <!-- Facebook claims provider -->
    <ClaimsProvider>
      <DisplayName>Facebook</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Facebook-OAUTH">
          <Metadata>
            <!--Demo action required: Change to your Facebook App Id-->
            <Item Key="client_id">313412440187068</Item>
            <Item Key="scope">email public_profile</Item>
            <Item Key="ClaimsEndpoint">https://graph.facebook.com/me?fields=id,first_name,last_name,name,email</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>


    <ClaimsProvider>
      <DisplayName>Local Account SignIn</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="login-NonInteractive">
          <Metadata>
            <Item Key="client_id">44444444-2222-2222-2222-555555555555</Item>
            <Item Key="IdTokenAudience">44444444-2222-2222-2222-555555555555</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="44444444-2222-2222-2222-555555555555" />
            <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="44444444-2222-2222-2222-555555555555" />
          </InputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

  </ClaimsProviders>

  <UserJourneys>
    <UserJourney Id="SignUpOrSignInWithForcePasswordReset">
      <OrchestrationSteps>
      
        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection TargetClaimsExchangeId="FacebookExchange" />
           <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
          </ClaimsProviderSelections>
          <ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- Check if the user has selected to sign in using one of the social providers -->
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="FacebookExchange" TechnicalProfileReferenceId="Facebook-OAUTH" />
           <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- For social IDP authentication, attempt to find the user account in the directory. -->
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>localAccountAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- Show self-asserted page only if the directory does not have the user account already (i.e. we do not have an objectId). 
          This can only happen when authentication happened using a social IDP. If local account was created or authentication done
          using ESTS in step 2, then an user account must exist in the directory by this time. -->
        <OrchestrationStep Order="4" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- This step reads any user attributes that we may not have received when authenticating using ESTS so they can be sent 
          in the token. -->
        <OrchestrationStep Order="5" 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>
        <!--Demo: check if change password is required. If yes, ask the user to reset the password-->
        <OrchestrationStep Order="6" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>socialIdpAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
              <Value>extension_mustResetPassword</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>            
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>extension_mustResetPassword</Value>
              <Value>True</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>            
          </Preconditions>        
          <ClaimsExchanges>
            <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
          <!--Demo: check if change password is required. If yes remove the value of the extension attribute. 
              So, on the next time user dons' t need to update the password-->
        <OrchestrationStep Order="7" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>socialIdpAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
              <Value>extension_mustResetPassword</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>            
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>extension_mustResetPassword</Value>
              <Value>True</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>            
          </Preconditions>        
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserRemoveMustResetPasswordUsingObjectId" TechnicalProfileReferenceId="AAD-UserRemoveMustResetPasswordUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- The previous step (SelfAsserted-Social) could have been skipped if there were no attributes to collect 
             from the user. So, in that case, create the user in the directory if one does not already exist 
             (verified using objectId which would be set from the last step if account was created in the directory. -->
        <OrchestrationStep Order="8" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
          </ClaimsExchanges>
        </OrchestrationStep>
 
        <OrchestrationStep Order="9" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
 
      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
  </UserJourneys>

</TrustFrameworkPolicy>
<TrustFrameworkPolicy
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
  PolicySchemaVersion="0.3.0.0"
  TenantId="resetpasswordtest.onmicrosoft.com"
  PolicyId="B2C_1A_signup_signin"
  PublicPolicyUri="http://resetpasswordtest.onmicrosoft.com/B2C_1A_signup_signin">

  <BasePolicy>
    <TenantId>resetpasswordtest.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
  </BasePolicy>

  <RelyingParty>
    <DefaultUserJourney ReferenceId="SignUpOrSignInWithForcePasswordReset" />
    <TechnicalProfile Id="PolicyProfile">
      <DisplayName>PolicyProfile</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="displayName" />
        <OutputClaim ClaimTypeReferenceId="givenName" />
        <OutputClaim ClaimTypeReferenceId="surname" />
        <OutputClaim ClaimTypeReferenceId="email" />
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
        <OutputClaim ClaimTypeReferenceId="identityProvider" />
        <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
      </OutputClaims>
      <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
  </RelyingParty>
</TrustFrameworkPolicy>

推荐答案

您错过了为扩展属性支持配置策略。 https://docs.microsoft.com/en-us/azure/active-directory-b2c/user-flow-custom-attributes?pivots=b2c-custom-policy#azure-ad-b2c-extensions-app

在开始使用样本之前,可以使用我的工具https://aka.ms/iefsetup自动执行整个过程。

这篇关于首次登录时重置密码期间发生Azure AD B2C错误(使用自定义策略)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆