4
votes

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>

2
The general recommendation when starting with Custom policies is to start with started packs Get started with custom policies in Azure Active Directory B2C Then work on to achieve your specific scenarios. Let us know if you still run into the issue and we can update the question/answersAbhishek Agrawal
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
Let me see if account linking sample has any issue.Abhishek Agrawal
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
I believe @ChrisPadgett has answered the question above.Abhishek Agrawal

2 Answers

2
votes

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>
0
votes

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.