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@#$%^&*\-_+=[\]{}|\\:',?/`~"();!]|\.(?!@)){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: @ # $ % ^ & * - _ + = [ ] { } | \ : ' , ? / ` ~ " ( ) ; ." />
</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@#$%^&*\-_+=[\]{}|\\:',?/`~"();!]|\.(?!@)){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@#$%^&*\-_+=[\]{}|\\:',?/`~"();!]|\.(?!@)){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: @ # $ % ^ & * - _ + = [ ] { } | \ : ' , ? / ` ~ " ( ) ; ." />
</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@#$%^&*\-_+=[\]{}|\\:',?/`~"();!]|\.(?!@)){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: @ # $ % ^ & * - _ + = [ ] { } | \ : ' , ? / ` ~ " ( ) ; ." />
</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