azure-ad-b2c-custom-policyclaims

how to add a custom claim to a web token? b2c custom policys


I have a custom policy on Azure B2C. When the user signs up, I need to remove the display for "DisplayName" (text box) from the signup screen. Instead, I need to copy the email into DisplayName and add the DisplayName to the web token.

I have succesfully completed the first part, I no longer ask the user for the displayName, but I am not getting DisplayName in the token, so I can't know if I am copying it right. I tried to copy and modify given_name, as that one works, but apparently something went wrong along the lines. How do I achieve that? or what I am missing?

My custom policy:

  <RelyingParty>
    <DefaultUserJourney ReferenceId="SignUpOrSignIn" />
    <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>

Base file:

 <ClaimType Id="displayName">
        <DisplayName>Display Name</DisplayName>
        <DataType>string</DataType>
        <UserHelpText>Your display name.</UserHelpText>
      </ClaimType>

...

<ClaimsTransformation Id="CopyEmailAddress" TransformationMethod="CopyClaim">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="inputClaim"/>
        </InputClaims>
        <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="displayName" TransformationClaimType="outputClaim"/>
      </OutputClaims>
    </ClaimsTransformation>

...

<TechnicalProfiles>
        <TechnicalProfile Id="login-NonInteractive">
          <DisplayName>Local Account SignIn</DisplayName>
          <Protocol Name="OpenIdConnect" />
          <Metadata>
            <Item Key="ProviderName">https://sts.windows.net/</Item>
            <Item Key="METADATA">https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration</Item>
    <Item Key="authorization_endpoint">https://login.microsoftonline.com/{tenant}/oauth2/token</Item>
    <Item Key="response_types">id_token</Item>
    <Item Key="response_mode">query</Item>
    <Item Key="scope">email openid</Item>

    <!-- Policy Engine Clients -->
    <Item Key="UsePolicyInRedirectUri">false</Item>
    <Item Key="HttpBinding">POST</Item>
  </Metadata>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username" Required="true" />
    <InputClaim ClaimTypeReferenceId="password" Required="true" />
    <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" AlwaysUseDefaultValue="true" />
    <InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" AlwaysUseDefaultValue="true" />
    <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" />
    <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" />
    <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
    <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
    <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="email" />
    <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
    <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
  </OutputClaims>
</TechnicalProfile>

....


Solution

  • Try to use in your login-Noninteractive your displayName claim like this:

    ClaimTypeReferenceId="email" PartnerClaimType="displayName"

    You really don't need the claims transformation "CopyEmailAddress"

    Basically what PartnerClaimType does is map the referenced Claim to another claim based on your Claim Schema.

    Regards.