1

Scenario: the user will get an invite link, which the admin triggers. The link will navigate the user to "change password" dialog with Azure ADB2C, where the user finishes the registration by giving a new password to the account. I am trying to pre-populate the the email field and set it to read-only.

I set up everything in the Azure part, the applications IdentityExperienceFramework and ProxyIdentityExperienceFramework.

I uploaded the TrustFrameworkBase.xml, which I got from the starter repo.

<?xml version="1.0" encoding="utf-8"?>
  <TrustFrameworkPolicy xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
PolicySchemaVersion="0.3.0.0"
TenantId="mydevtenant.onmicrosoft.com"
PolicyId="B2C_1A_TrustFrameworkBase"
PublicPolicyUri="http://mydevtenant.onmicrosoft.com/B2C_1A_TrustFrameworkBase">

  <BuildingBlocks>
    <ClaimsSchema>
      <ClaimType Id="email">
        <DisplayName>Email Address</DisplayName>
        <DataType>string</DataType>
        <DefaultPartnerClaimTypes>
          <Protocol Name="OAuth2" PartnerClaimType="email" />
        </DefaultPartnerClaimTypes>
        <UserHelpText>Email used for account confirmation</UserHelpText>
      </ClaimType>

      <ClaimType Id="newPassword">
        <DisplayName>New Password</DisplayName>
        <DataType>string</DataType>
        <UserHelpText>Enter new password</UserHelpText>
        <UserInputType>Password</UserInputType>
        <Restriction>
          <Pattern
            RegularExpression="^((?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]))([A-Za-z\d@#$%^&amp;*\-_+=[\]{}|\\:',?/`~&quot;();!]|\.(?!@)){8,16}$"
            HelpText="8-16 characters, containing 3 out of 4 of the following: Lowercase characters, uppercase characters, digits (0-9), and one or more of the following symbols: @ # $ % ^ &amp; * - _ + = [ ] { } | \ : ' , ? / ` ~ &quot; ( ) ; ." />
        </Restriction>
      </ClaimType>

      <ClaimType Id="reenterPassword">
        <DisplayName>Confirm New Password</DisplayName>
        <DataType>string</DataType>
        <UserHelpText>Confirm new password</UserHelpText>
        <UserInputType>Password</UserInputType>
        <Restriction>
          <Pattern
            RegularExpression="^((?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]))([A-Za-z\d@#$%^&amp;*\-_+=[\]{}|\\:',?/`~&quot;();!]|\.(?!@)){8,16}$"
            HelpText=" " />
        </Restriction>
      </ClaimType>
    </ClaimsSchema> 
  </BuildingBlocks>

  <ClaimsProviders>
    <ClaimsProvider>
      <DisplayName>Token Issuer</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="TpEngine_c3bd4fe2-1775-4013-b91d-35f16d377d13">
          <DisplayName>TPEngine</DisplayName>
          <Protocol Name="None" />
          <Metadata>
            <Item Key="url">https://mydevtenant.b2clogin.com/mydevtenant.onmicrosoft.com</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
  </ClaimsProviders>
</TrustFrameworkPolicy>

Uploading it works fine.

But when I try to upload the TrustFrameworkExtensions.xml then things get complicated. I tried different fixes suggested by other GitHub projects, tutorials and Copilot, and every time it gives me a different but similar error when I try to upload it.

This is my current TrustFrameworkExtensions.xml validation:

<?xml version="1.0" encoding="utf-8"?>
<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="mydevtenant.onmicrosoft.com"
         PolicyId="B2C_1A_TrustFrameworkExtensions"
         PublicPolicyUri="http://mydevtenant.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">

  <BasePolicy>
    <TenantId>mydevtenant.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
  </BasePolicy>

  <UserJourneys>
    <UserJourney Id="PasswordResetJourney">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="PrepopulateEmail" TechnicalProfileReferenceId="SelfAsserted-Email" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.selfasserted">
         <ClaimsExchanges>
           <ClaimsExchange Id="PasswordResetExchange" TechnicalProfileReferenceId="LocalAccountResetPassword" />
         </ClaimsExchanges>
        </OrchestrationStep>
      </OrchestrationSteps>
    </UserJourney>
  </UserJourneys>
</TrustFrameworkPolicy>

For this particular validation this is the error I get when trying to upload it:

Upload custom policy

Validation failed: 2 validation error(s) found in policy "B2C_1A_TRUSTFRAMEWORKEXTENSIONS" of tenant "mydevtenant.onmicrosoft.com".The following error occurred in orchestration step 1 in user journey "PasswordResetJourney" in policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com": Policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com" makes a reference to TechnicalProfile With id "SelfAsserted-Email" but neither the policy nor any of its base policies contain such an element. The following error occurred in orchestration step 1 in user journey "PasswordResetJourney" in policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com": Policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com" makes a reference to TechnicalProfile With id "SelfAsserted-Email" but neither the policy nor any of its base policies contain such an element.The following error occurred in orchestration step 1 in user journey "PasswordResetJourney" in policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com": Policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com" makes a reference to TechnicalProfile With id "SelfAsserted-Email" but neither the policy nor any of its base policies contain such an element.The following error occurred in orchestration step 1 in user journey "PasswordResetJourney" in policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com": Policy "B2C_1A_TrustFrameworkExtensions" of tenant "mydevtenant.onmicrosoft.com" makes a reference to TechnicalProfile With id "SelfAsserted-Email" but neither the policy nor any of its base policies contain such an element.

I have tried many approaches and this is the recent one I've tried. There is also the PasswordReset.xml but I haven't gotten there yet. The policy is for the Local Accounts.

EDIT: Updated code of TrustFrameworkBase.xmland TrustFrameworkExtensions.xml

<?xml version="1.0" encoding="utf-8"?>
<TrustFrameworkPolicy xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  PolicySchemaVersion="0.3.0.0"
  TenantId="mydevtenant.onmicrosoft.com"
  PolicyId="B2C_1A_TrustFrameworkBase"
  PublicPolicyUri="http://mydevtenant.onmicrosoft.com/B2C_1A_TrustFrameworkBase">

<BuildingBlocks>

  <ClaimsSchema>

    <ClaimType Id="signInNames.emailAddress">
        <DisplayName>Email Address</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Email address to use for signing in.</UserHelpText>
            <UserInputType>TextBox</UserInputType>
        </ClaimType>

        <ClaimType Id="newPassword">
            <DisplayName>New Password</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Enter new password</UserHelpText>
            <UserInputType>Password</UserInputType>
            <Restriction>
                <Pattern
                    RegularExpression="^((?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]))([A-Za-z\d@#$%^&amp;*\-_+=[\]{}|\\:',?/`~&quot;();!]|\.(?!@)){8,16}$"
                    HelpText="8-16 characters, containing 3 out of 4 of the following: Lowercase characters, uppercase characters, digits (0-9), and one or more of the following symbols: @ # $ % ^ &amp; * - _ + = [ ] { } | \ : ' , ? / ` ~ &quot; ( ) ; ." />
            </Restriction>
        </ClaimType>

        <ClaimType Id="reenterPassword">
            <DisplayName>Confirm New Password</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Confirm new password</UserHelpText>
            <UserInputType>Password</UserInputType>
            <Restriction>
                <Pattern
                    RegularExpression="^((?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]))([A-Za-z\d@#$%^&amp;*\-_+=[\]{}|\\:',?/`~&quot;();!]|\.(?!@)){8,16}$"
                    HelpText="8-16 characters, containing 3 out of 4 of the following: Lowercase characters, uppercase characters, digits (0-9), and one or more of the following symbols: @ # $ % ^ &amp; * - _ + = [ ] { } | \ : ' , ? / ` ~ &quot; ( ) ; ." />
            </Restriction>
        </ClaimType>
    </ClaimsSchema>
</BuildingBlocks>

<ClaimsProviders>
    <ClaimsProvider>
        <DisplayName>Token Issuer</DisplayName>
        <TechnicalProfiles>
            <TechnicalProfile Id="TpEngine_c3bd4fe2-1775-4013-b91d-35f16d377d13">
                <DisplayName>TPEngine</DisplayName>
                <Protocol Name="None" />
                <Metadata>
                    <Item Key="url">https://mydevtenant.b2clogin.com/mydevtenant.onmicrosoft.com</Item>
                </Metadata>
            </TechnicalProfile>
        </TechnicalProfiles>
    </ClaimsProvider>
</ClaimsProviders>
</TrustFrameworkPolicy>

And

<?xml version="1.0" encoding="utf-8"?>
<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="mydevtenant.onmicrosoft.com"
 PolicyId="B2C_1A_TrustFrameworkExtensions"
 PublicPolicyUri="http://mydevtenant.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">

<BasePolicy>
  <TenantId>mydevtenant.onmicrosoft.com</TenantId>
  <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
</BasePolicy>

  <BuildingBlocks>

    <ClaimsSchema>

    <ClaimType Id="emailFromQuery">
      <DisplayName>Email Address</DisplayName>
      <DataType>string</DataType>
      <DefaultPartnerClaimTypes>
        <Protocol Name="OpenIdConnect" PartnerClaimType="signInNames.emailAddress" />
      </DefaultPartnerClaimTypes>
      <UserInputType>Readonly</UserInputType>
    </ClaimType>

  </ClaimsSchema>

<ClaimsTransformations>

  <ClaimsTransformation Id="CopyEmailToReadOnlyEmail" TransformationMethod="FormatStringClaim">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="emailFromQuery" TransformationClaimType="inputClaim" />
    </InputClaims>
    <InputParameters>
      <InputParameter Id="stringFormat" DataType="string" Value="{0}" />
    </InputParameters>
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="emailFromQuery" TransformationClaimType="outputClaim" />
    </OutputClaims>
  </ClaimsTransformation>

</ClaimsTransformations>

</BuildingBlocks>

<ClaimsProviders>

<ClaimsProvider>
  <DisplayName>Local Account</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="LocalAccountResetPasswordSignUp">
      <DisplayName>Reset password using email address</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine" />
        <InputClaims>
              <InputClaim ClaimTypeReferenceId="emailFromQuery" DefaultValue="{OIDC:email}" AlwaysUseDefaultValue="true" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="emailFromQuery" />
        </OutputClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Token Issuer</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="TpEngine_c3bd4fe2-1775-4013-b91d-35f16d377d13">
      <DisplayName>TPEngine</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <Metadata>
        <Item Key="url">https://mydevtenant.b2clogin.com/mydevtenant.onmicrosoft.com</Item>
      </Metadata>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Token Issuer</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="JwtIssuer">
      <DisplayName>JWT Issuer</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <OutputTokenFormat>JWT</OutputTokenFormat>
      <Metadata>
        <Item Key="client_id">{service:te}</Item>
        <Item Key="issuer_refresh_token_user_identity_claim_type">objectId</Item>
        <Item Key="SendTokenResponseBodyWithJsonNumbers">true</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
        <Key Id="issuer_refresh_token_key" StorageReferenceId="B2C_1A_TokenEncryptionKeyContainer" />
      </CryptographicKeys>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-jwt-issuer" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

<ClaimsProvider>
  <DisplayName>Session Management</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="SM-jwt-issuer">
      <DisplayName>Session Management Provider</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.OAuthSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

</ClaimsProviders>

<UserJourneys>
  <UserJourney Id="PasswordResetJourney">

    <OrchestrationSteps>
      <OrchestrationStep Order="1" Type="ClaimsExchange">
        <ClaimsProviderSelections>
          <ClaimsProviderSelection ValidationClaimsExchangeId="PrepopulateEmail" />
        </ClaimsProviderSelections>
        <ClaimsExchanges>
          <ClaimsExchange Id="PrepopulateEmail" TechnicalProfileReferenceId="LocalAccountResetPasswordSignUp" />
        </ClaimsExchanges>
      </OrchestrationStep>

    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="PasswordResetExchange" TechnicalProfileReferenceId="LocalAccountResetPasswordSignUp" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

  </OrchestrationSteps>
</UserJourney>
</UserJourneys>

</TrustFrameworkPolicy>

In addition I added te PasswordReset.xml too

<?xml version="1.0" encoding="utf-8"?>
<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="mydevtenant.onmicrosoft.com"
  PolicyId="B2C_1A_PasswordReset"
  PublicPolicyUri="http://mydevtenant.onmicrosoft.com/B2C_1A_PasswordReset">

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

<RelyingParty>
  <DefaultUserJourney ReferenceId="PasswordResetJourney" />
  <TechnicalProfile Id="PolicyProfile">
    <DisplayName>PolicyProfile</DisplayName>
    <Protocol Name="OpenIdConnect" />
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="emailFromQuery" />
    </OutputClaims>
    <SubjectNamingInfo ClaimType="sub" />
  </TechnicalProfile>
</RelyingParty>
</TrustFrameworkPolicy>

And I am getting the following error when uploading.

Validation failed: 1 validation error(s) foun in policy "B2C_1A_PasswordReset" of tenant "mydevtenant.onmicrosoft.com". A TechnicalProfile with ID "PolicyProfile" must specify a subject identifier claim via SubjectNamingInfo that matches an OutputClaim in order to user the OpenIdConnectProtocolA TechnicalProfile with ID "PolicyProfile" must specify a subject identifier claim via SubjectNamingInfo that matches an OutputClaim in order to user the OpenIdConnectProtocol

2
  • 3
    The issue is mentioned in the error. You are referencing a technical profile with Id "SelfAsserted-Email", but have not defined it. In your use case, you'd probably need something similar to what they do here: github.com/azure-ad-b2c/samples/tree/master/policies/…. The link contains a signed token from which AD B2C extracts the email into a claim. The user can then enter a password and then you can write the user through a validation profile. Commented Oct 22 at 7:49
  • @juunas thank you for pointing that out. I recognize that my policy has a lot of error, but I already tried a lot. Anyway, I will post my new policy as an answer, and also the validation errors with it. I hope you can help me or guide me further. Commented Oct 23 at 6:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.