title: Write a custom attribute in AAD B2C during a google sign-up journey
body: <p>I'm trying to <strong>write a custom attribute value</strong> (into AAD B2C) during a sign-up with email invitation.</p>
  
  <p>It <strong>works well</strong> with AAD B2C <strong>local accounts</strong>.</p>
  
  <p>It <strong>doesn't work</strong> with <strong>Google accounts</strong>.</p>
  
  <p>I use a combination of :</p>
  
  <ul>
  <li>the SocialAndLocalAccounts version of the starter pack : <a href="https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/tree/master/SocialAndLocalAccounts" rel="nofollow noreferrer">https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/tree/master/SocialAndLocalAccounts</a></li>
  <li>the "sign-up with email invitation" example provided by the community : <a href="https://github.com/azure-ad-b2c/samples/tree/master/policies/invite" rel="nofollow noreferrer">https://github.com/azure-ad-b2c/samples/tree/master/policies/invite</a></li>
  <li>Microsoft's documentation to set-up Google custom policies : <a href="https://docs.microsoft.com/fr-fr/azure/active-directory-b2c/active-directory-b2c-setup-goog-app" rel="nofollow noreferrer">https://docs.microsoft.com/fr-fr/azure/active-directory-b2c/active-directory-b2c-setup-goog-app</a></li>
  <li>some custom attributes exemples : <a href="https://medium.com/the-new-control-plane/working-with-custom-attributes-in-azure-ad-b2c-custom-policies-fae1454b12bf" rel="nofollow noreferrer">https://medium.com/the-new-control-plane/working-with-custom-attributes-in-azure-ad-b2c-custom-policies-fae1454b12bf</a> et <a href="https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-create-custom-attributes-profile-edit-custom#next-steps" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-create-custom-attributes-profile-edit-custom#next-steps</a></li>
  </ul>
  
  <p>Here is the custom attribute that I use :</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;ClaimsSchema&gt;
    &lt;ClaimType Id="extension_externalid"&gt;
      &lt;DisplayName&gt;My External Application Identifier&lt;/DisplayName&gt;
      &lt;DataType&gt;string&lt;/DataType&gt;
      &lt;UserHelpText&gt;External Application Identifier&lt;/UserHelpText&gt;
      &lt;UserInputType&gt;Readonly&lt;/UserInputType&gt;
    &lt;/ClaimType&gt;
  &lt;/ClaimsSchema&gt;
  </code></pre>
  
  <p>The "google account sign-up with email invitation" UserJourney :</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;UserJourney Id="SignUpInvitation"&gt;
    &lt;OrchestrationSteps&gt;
  
      &lt;OrchestrationStep Order="1" Type="GetClaims" CpimIssuerTechnicalProfileReferenceId="IdTokenHint_ExtractClaims" /&gt;
  
      &lt;OrchestrationStep Order="2" Type="ClaimsExchange"&gt;
       &lt;Preconditions&gt;
          &lt;Precondition Type="ClaimsExist" ExecuteActionsIf="true"&gt;
            &lt;Value&gt;email&lt;/Value&gt;
            &lt;Action&gt;SkipThisOrchestrationStep&lt;/Action&gt;
          &lt;/Precondition&gt;
        &lt;/Preconditions&gt;        
        &lt;ClaimsExchanges&gt;
          &lt;ClaimsExchange Id="SelfAsserted-Unsolicited" TechnicalProfileReferenceId="SelfAsserted-Unsolicited"/&gt;
        &lt;/ClaimsExchanges&gt;
      &lt;/OrchestrationStep&gt;
  
      &lt;OrchestrationStep Order="3" Type="ClaimsExchange"&gt;
        &lt;ClaimsExchanges&gt;
          &lt;ClaimsExchange Id="GoogleExchange" TechnicalProfileReferenceId="Google-OAUTH" /&gt;
        &lt;/ClaimsExchanges&gt;
      &lt;/OrchestrationStep&gt;
  
      &lt;OrchestrationStep Order="4" Type="ClaimsExchange"&gt;
        &lt;Preconditions&gt;
          &lt;Precondition Type="ClaimEquals" ExecuteActionsIf="true"&gt;
            &lt;Value&gt;authenticationSource&lt;/Value&gt;
            &lt;Value&gt;localAccountAuthentication&lt;/Value&gt;
            &lt;Action&gt;SkipThisOrchestrationStep&lt;/Action&gt;
          &lt;/Precondition&gt;
        &lt;/Preconditions&gt;
        &lt;ClaimsExchanges&gt;
          &lt;ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" /&gt;
        &lt;/ClaimsExchanges&gt;
      &lt;/OrchestrationStep&gt;
  
      &lt;OrchestrationStep Order="5" Type="ClaimsExchange"&gt;
        &lt;Preconditions&gt;
          &lt;Precondition Type="ClaimsExist" ExecuteActionsIf="true"&gt;
            &lt;Value&gt;objectId&lt;/Value&gt;
            &lt;Action&gt;SkipThisOrchestrationStep&lt;/Action&gt;
          &lt;/Precondition&gt;
        &lt;/Preconditions&gt;
        &lt;ClaimsExchanges&gt;
          &lt;ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" /&gt;
        &lt;/ClaimsExchanges&gt;
      &lt;/OrchestrationStep&gt;
  
      &lt;OrchestrationStep Order="6" Type="ClaimsExchange"&gt;
        &lt;Preconditions&gt;
          &lt;Precondition Type="ClaimEquals" ExecuteActionsIf="true"&gt;
            &lt;Value&gt;authenticationSource&lt;/Value&gt;
            &lt;Value&gt;socialIdpAuthentication&lt;/Value&gt;
            &lt;Action&gt;SkipThisOrchestrationStep&lt;/Action&gt;
          &lt;/Precondition&gt;
        &lt;/Preconditions&gt;
        &lt;ClaimsExchanges&gt;
          &lt;ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /&gt;
        &lt;/ClaimsExchanges&gt;
      &lt;/OrchestrationStep&gt;
  
      &lt;OrchestrationStep Order="7" Type="ClaimsExchange"&gt;
        &lt;Preconditions&gt;
          &lt;Precondition Type="ClaimsExist" ExecuteActionsIf="true"&gt;
            &lt;Value&gt;objectId&lt;/Value&gt;
            &lt;Action&gt;SkipThisOrchestrationStep&lt;/Action&gt;
          &lt;/Precondition&gt;
        &lt;/Preconditions&gt;
        &lt;ClaimsExchanges&gt;
          &lt;ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityIdWithUserAttributes" /&gt;
        &lt;/ClaimsExchanges&gt;
      &lt;/OrchestrationStep&gt;
  
      &lt;OrchestrationStep Order="8" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer"/&gt;
  
    &lt;/OrchestrationSteps&gt;
    &lt;ClientDefinition ReferenceId="DefaultWeb"/&gt;
  &lt;/UserJourney&gt;
  </code></pre>
  
  <p>And the technical profile that should write my custom attribute into AAD B2C but doesn't :</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;TechnicalProfile Id="AAD-UserWriteUsingAlternativeSecurityIdWithUserAttributes"&gt;
    &lt;Metadata&gt;
      &lt;Item Key="Operation"&gt;Write&lt;/Item&gt;
      &lt;Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists"&gt;true&lt;/Item&gt;
      &lt;Item Key="UserMessageIfClaimsPrincipalAlreadyExists"&gt;You are already registered, please press the back button and sign in instead.&lt;/Item&gt;
    &lt;/Metadata&gt;
    &lt;IncludeInSso&gt;false&lt;/IncludeInSso&gt;
    &lt;InputClaimsTransformations&gt;
      &lt;InputClaimsTransformation ReferenceId="CreateOtherMailsFromEmail" /&gt;
    &lt;/InputClaimsTransformations&gt;
    &lt;InputClaims&gt;
      &lt;InputClaim ClaimTypeReferenceId="AlternativeSecurityId" PartnerClaimType="alternativeSecurityId" Required="true" /&gt;
    &lt;/InputClaims&gt;
    &lt;PersistedClaims&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="alternativeSecurityId" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="userPrincipalName" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="mailNickName" DefaultValue="unknown" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="displayName" DefaultValue="unknown" /&gt;
  
      &lt;PersistedClaim ClaimTypeReferenceId="otherMails" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="givenName" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="surname" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="extension_externalid" /&gt;
    &lt;/PersistedClaims&gt;
    &lt;OutputClaims&gt;
      &lt;OutputClaim ClaimTypeReferenceId="objectId" /&gt;
      &lt;OutputClaim ClaimTypeReferenceId="newUser" PartnerClaimType="newClaimsPrincipalCreated" /&gt;
      &lt;OutputClaim ClaimTypeReferenceId="otherMails" /&gt;
    &lt;/OutputClaims&gt;
    &lt;IncludeTechnicalProfile ReferenceId="AAD-Common" /&gt;
    &lt;UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" /&gt;
  &lt;/TechnicalProfile&gt;
  </code></pre>
  
  <p>For example, here is the technical profile that works well for local accounts :</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;TechnicalProfiles&gt;
  &lt;TechnicalProfile Id="AAD-UserWriteUsingLogonEmailWithUserAttributes"&gt;
    &lt;Metadata&gt;
      &lt;Item Key="Operation"&gt;Write&lt;/Item&gt;
      &lt;Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists"&gt;true&lt;/Item&gt;
    &lt;/Metadata&gt;
    &lt;IncludeInSso&gt;false&lt;/IncludeInSso&gt;
    &lt;InputClaims&gt;
      &lt;InputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" Required="true" /&gt;
    &lt;/InputClaims&gt;
    &lt;PersistedClaims&gt;
      &lt;!-- Required claims --&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="newPassword" PartnerClaimType="password"/&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="displayName" DefaultValue="unknown" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="passwordPolicies" DefaultValue="DisablePasswordExpiration" /&gt;
  
      &lt;!-- Optional claims. --&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="givenName" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="surname" /&gt;
      &lt;PersistedClaim ClaimTypeReferenceId="extension_externalid" /&gt;
    &lt;/PersistedClaims&gt;
    &lt;OutputClaims&gt;
      &lt;OutputClaim ClaimTypeReferenceId="objectId" /&gt;
      &lt;OutputClaim ClaimTypeReferenceId="newUser" PartnerClaimType="newClaimsPrincipalCreated" /&gt;
      &lt;OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" /&gt;
      &lt;OutputClaim ClaimTypeReferenceId="userPrincipalName" /&gt;
      &lt;OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" /&gt;
    &lt;/OutputClaims&gt;
    &lt;IncludeTechnicalProfile ReferenceId="AAD-Common" /&gt;
    &lt;UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" /&gt;
  &lt;/TechnicalProfile&gt;
  </code></pre>
  
  <p>Note that I use an id_token_hint to set the <em>extension_externalid</em> value :</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;ClaimsProvider&gt;
    &lt;DisplayName&gt;My ID Token Hint ClaimsProvider&lt;/DisplayName&gt;
    &lt;TechnicalProfiles&gt;
      &lt;TechnicalProfile Id="IdTokenHint_ExtractClaims"&gt;
        &lt;DisplayName&gt;My ID Token Hint TechnicalProfile&lt;/DisplayName&gt;
        &lt;Protocol Name="None" /&gt;
        &lt;Metadata&gt;
          &lt;Item Key="METADATA"&gt;https://XXXXXXXXXXXXX.azurewebsites.net/.well-known/openid-configuration&lt;/Item&gt;
        &lt;/Metadata&gt;
        &lt;OutputClaims&gt;
          &lt;!--Sample: Read the claims from the id_token_hint--&gt;
          &lt;OutputClaim ClaimTypeReferenceId="email" /&gt;
          &lt;OutputClaim ClaimTypeReferenceId="state" /&gt;
          &lt;OutputClaim ClaimTypeReferenceId="extension_externalid" /&gt;
        &lt;/OutputClaims&gt;
      &lt;/TechnicalProfile&gt;
    &lt;/TechnicalProfiles&gt;
  &lt;/ClaimsProvider&gt;
  </code></pre>
  
  <p>I checked that extension_externalid value is correct in the TechnicalProfile "SelfAsserted-Social" (adding it temporarily as input and output claim).</p>
  
  <p>I expect the provided extension_externalid value to be writen in AAD B2C. So I can access it through API Graph AAD or in the sign-in JWT token.</p>
  
  <p>Any help please?</p>