4

I'm switching our app from using built-in user flows to custom policies so that we can enable some features that we need like account linking and REST integration.

My TrustFrameworkBase.xml and TrustFrameworkExtensions.xml policy files both upload fine. But when I try uploading the relying party file I'm hitting a validation error that I can't explain:

Validation failed: 2 validation error(s) found in policy "B2C_1A_SIGNUP" of tenant "HyperProofLocalDev.onmicrosoft.com".Input Claim 'alternativeSecurityIds' is not supported in Azure Active Directory Provider technical profile 'AAD-UserWriteUsingAlternativeSecurityId' of policy 'B2C_1A_SignUp'.Input Claim 'emails' is not supported in Azure Active Directory Provider technical profile 'AAD-UserCreateEmailsClaim' of policy 'B2C_1A_SignUp'.

I followed guidance online such as this post to add support for these claims. Haven't been able to determine why B2C thinks these are unsupported.

Here's what I have for emails in TrustFrameworkBase.xml:

      <ClaimType Id="emails">
        <DisplayName>Emails</DisplayName>
        <DataType>stringCollection</DataType>
        <UserHelpText>User's email addresses</UserHelpText>
      </ClaimType>
      <ClaimsTransformation Id="GetFirstOtherMail" TransformationMethod="GetSingleItemFromStringCollection">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="otherMails" TransformationClaimType="collection" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="firstOtherMail" TransformationClaimType="extractedItem" />
        </OutputClaims>
      </ClaimsTransformation>

      <ClaimsTransformation Id="CopyFirstOtherMailToEmails" TransformationMethod="AddItemToStringCollection">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="firstOtherMail" TransformationClaimType="item" />
          <InputClaim ClaimTypeReferenceId="emails" TransformationClaimType="collection" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="emails" TransformationClaimType="collection" />
        </OutputClaims>
      </ClaimsTransformation>

      <ClaimsTransformation Id="CopySignInNamesEmailToEmails" TransformationMethod="AddItemToStringCollection">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="signInNames.emailAddress" TransformationClaimType="item" />
          <InputClaim ClaimTypeReferenceId="emails" TransformationClaimType="collection" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="emails" TransformationClaimType="collection" />
        </OutputClaims>
      </ClaimsTransformation>
        <TechnicalProfile Id="AAD-UserCreateEmailsClaim">
          <Metadata>
            <Item Key="Operation">Read</Item>
            <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
          </Metadata>
          <IncludeInSso>false</IncludeInSso>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="emails" />           
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="GetFirstOtherMail"/>
            <OutputClaimsTransformation ReferenceId="CopySignInNamesEmailToEmails"/>
            <OutputClaimsTransformation ReferenceId="CopyFirstOtherMailToEmails"/>
          </OutputClaimsTransformations>
          <IncludeTechnicalProfile ReferenceId="AAD-Common" />
        </TechnicalProfile>

And here's the relying party file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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="hyperprooflocaldev.onmicrosoft.com"
  PolicyId="B2C_1A_SignUp"
  PublicPolicyUri="http://hyperprooflocaldev.onmicrosoft.com/B2C_1A_SignUp"  
  DeploymentMode="Development"
  UserJourneyRecorderEndpoint="urn:journeyrecorder:applicationinsights"
  >

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

  <RelyingParty>
    <DefaultUserJourney ReferenceId="SignUp" />
    <UserJourneyBehaviors>
      <SessionExpiryType>Rolling</SessionExpiryType>
      <SessionExpiryInSeconds>86400</SessionExpiryInSeconds>
      <JourneyInsights TelemetryEngine="ApplicationInsights" InstrumentationKey="451d3a92-fb38-4a1b-9b77-2f6572677090" DeveloperMode="true" ClientEnabled="false" ServerEnabled="true" TelemetryVersion="1.0.0" />
      <ContentDefinitionParameters>
        <Parameter Name="emailAddress">{OIDC:LoginHint}</Parameter>
        <Parameter Name="givenName">{OAUTH-KV:givenName}</Parameter>
        <Parameter Name="surname">{OAUTH-KV:surname}</Parameter>
      </ContentDefinitionParameters>
      <ScriptExecution>Allow</ScriptExecution>
    </UserJourneyBehaviors>    

    <TechnicalProfile Id="PolicyProfile">
      <DisplayName>PolicyProfile</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="displayName" />
        <OutputClaim ClaimTypeReferenceId="email" />
        <OutputClaim ClaimTypeReferenceId="emails" />
        <OutputClaim ClaimTypeReferenceId="givenName" />
        <OutputClaim ClaimTypeReferenceId="identityProvider" />
        <OutputClaim ClaimTypeReferenceId="surname" />
        <OutputClaim ClaimTypeReferenceId="newUser" />
        <OutputClaim ClaimTypeReferenceId="objectId" />
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
        <OutputClaim ClaimTypeReferenceId="trustFrameworkPolicy" Required="true" DefaultValue="{policy}" />
      </OutputClaims>
      <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
  </RelyingParty>
</TrustFrameworkPolicy>

Andrew Miller
  • 105
  • 1
  • 9
  • The general recommendation when starting with Custom policies is to start with started packs [Get started with custom policies in Azure Active Directory B2C](https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-get-started-custom) Then work on to achieve your specific scenarios. Let us know if you still run into the issue and we can update the question/answers – Abhishek Agrawal May 18 '19 at 21:09
  • Thanks Abhishek. Because we are interested in account linking I started with the account linking sample from the advanced examples. I'll start the excercise over using the starter pack as a base and report back. – Andrew Miller May 19 '19 at 15:58
  • Let me see if account linking sample has any issue. – Abhishek Agrawal May 20 '19 at 16:32
  • Abishek I started from scratch using the SocialAndLocalAccounts policy files from the starter pack. I added our preferred social provider (Google) and then uploaded all files without error. I then added in support for the emails claim as per the description above and got the same error about emails being not supported. – Andrew Miller May 21 '19 at 01:14
  • I believe @ChrisPadgett has answered the question above. – Abhishek Agrawal May 21 '19 at 05:24
  • This post doesn't work, [this](https://stackoverflow.com/questions/47145452/return-emails-on-custom-policies) one does. – ton.yeung Apr 21 '21 at 20:37

2 Answers2

4

The user object has the otherMails property rather than the emails property which is why the error is occurring.

Assuming that you have declared the signInNames.emailAddress and otherMails claim types, then you must modify the AAD-UserCreateEmailsClaim technical profile, as follows, to read both the signInNames.emailAddress and otherMails properties for the user object before they are processed by the output claims transformations:

<TechnicalProfile Id="AAD-UserCreateEmailsClaim">
  <Metadata>
    <Item Key="Operation">Read</Item>
    <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
  </Metadata>
  <IncludeInSso>false</IncludeInSso>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />           
    <OutputClaim ClaimTypeReferenceId="otherMails" />           
  </OutputClaims>
  <OutputClaimsTransformations>
    <OutputClaimsTransformation ReferenceId="GetFirstOtherMail"/>
    <OutputClaimsTransformation ReferenceId="CopySignInNamesEmailToEmails"/>
    <OutputClaimsTransformation ReferenceId="CopyFirstOtherMailToEmails"/>
  </OutputClaimsTransformations>
  <IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
Chris Padgett
  • 14,186
  • 1
  • 15
  • 28
  • 1
    Thanks Chris. This seems to have gotten me past the emails issue. As noted in the original error I was seeing a similar problem with alternativeSecurityIds. Following Abhishek Agrawal's advice I'm in the process of rebuilding our policies using the starter pack examples as a base. I hope to add in the alternativeSeucurityIds piece later today and will hopefully close this out then. – Andrew Miller May 21 '19 at 17:19
  • Hi Andrew. Can you please add the technical profile, which refers to the "alternativeSecurityIds" claim, to the above question? – Chris Padgett May 21 '19 at 21:35
  • Using information in [this aricle](https://docs.microsoft.com/en-us/azure/active-directory-b2c/social-transformations) (which has some issues) and the account linking example (which is somewhat [out of date](https://github.com/Azure-Samples/active-directory-b2c-advanced-policies/issues/50)) I've been able to work past my earlier issues. I was able to add alternativeSecurityIds to **AAD-UserReadUsingAlternativeSecurityId** and **AAD-UserWriteUsingAlternativeSecurityId** in my new `TrustFrameworkBase.xml`. I have more work to do to get account linking to work but I think I'm unblocked. – Andrew Miller May 23 '19 at 15:51
  • 1
    @AndrewMiller how were you able to solve the error relating to the alternativeSecurityIds? I'm also getting a `.Input Claim 'alternativeSecurityIds' is not supported in Azure Active Directory Provider technical profile 'AAD-UserWriteUsingAlternativeSecurityId'` – sgdesmet Sep 03 '19 at 15:46
0

In the AAD technical profiles you have (mentioned in the validation message), you have emails as the OutputClaim. However, such a property does not exist in AD Graph (which is used by AzureActiveDirectoryProvider). IEF is complaining because it's impossible to source its value.

When you add an OutputClaimsTransformation♧, emails claim will be created because it is an OutputClaim of the transformation. It does not need to be added to the technical profile.

This check was recently added to help policy authors understand which claims could not be sourced but because of documentation it is being switched off currently. It will be added once, based on such feedback, we can figure out how to roll it out while we can also help policy authors address the issues easily.

Omer Iqbal
  • 2,245
  • 10
  • 15