azure-ad-b2cazure-ad-b2c-custom-policy

Schema Validation Errors with <ClaimsTransformations> in Azure AD B2C Custom Policy


I am experiencing persistent schema validation errors when uploading my Azure AD B2C custom policy, specifically related to the <ClaimsTransformations> section. The error message is not always the same, but it typically states:

The element 'ClaimsTransformation' in namespace 'http://schemas.microsoft.com/online/cpim/schemas/2013/06' has invalid child element 'InputClaims' in namespace 'http://schemas.microsoft.com/online/cpim/schemas/2013/06'. List of possible elements expected: 'OutputClaims' in namespace 'http://schemas.microsoft.com/online/cpim/schemas/2013/06'.**

Key Details:

What I’ve Tried:

<!-- ===== Transformations ===== -->
<ClaimsTransformations>
    <ClaimsTransformation Id="CopyObjectIdToUserId"
                          TransformationMethod="CopyClaim">
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId"
                         TransformationClaimType="inputClaim" />
            <OutputClaim ClaimTypeReferenceId="userId"
                         TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
    <ClaimsTransformation Id="CopyInviteTokenToSecretKey"
                          TransformationMethod="CopyClaim">
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="extension_d370edc869fd4e23ba22efa407bd8935_InviteToken"
                         TransformationClaimType="inputClaim" />
            <OutputClaim ClaimTypeReferenceId="secretKey"
                         TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
    <ClaimsTransformation Id="CreateIssuer"
                          TransformationMethod="FormatStringClaim">
        <InputParameters>
            <InputParameter Id="stringFormat"
                            DataType="string"
                            Value="{0}" />
        </InputParameters>
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="totpIssuer"
                        TransformationClaimType="inputClaim" />
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="totpIdentifier"
                         TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
    <ClaimsTransformation Id="FormatTotpLabel"
                          TransformationMethod="FormatStringMultipleClaims">
        <InputParameters>
            <InputParameter Id="stringFormat"
                            DataType="string"
                            Value="{0}:{1}" />
        </InputParameters>
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="totpIdentifier"
                        TransformationClaimType="inputClaim1" />
            <InputClaim ClaimTypeReferenceId="email"
                        TransformationClaimType="inputClaim2" />
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="totpLabel"
                         TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
    <ClaimsTransformation Id="CreateQrCodeUri"
                          TransformationMethod="BuildUri">
        <InputParameters>
            <InputParameter Id="scheme"
                            DataType="string"
                            Value="otpauth" />
            <InputParameter Id="path"
                            DataType="string"
                            Value="totp" />
        </InputParameters>
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="totpLabel"
                        TransformationClaimType="label" />
            <InputClaim ClaimTypeReferenceId="secretKey"
                        TransformationClaimType="secret" />
            <InputClaim ClaimTypeReferenceId="totpIssuer"
                        TransformationClaimType="issuer" />
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="qrCodeContent"
                         TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
</ClaimsTransformations>
<!-- ===== Content definitions ===== -->

Solution

  • For all ClaimsTransformation definitions the InputClaims element must come before InputParameters which comes before OutputClaims (doc example).

    So, for example:

    <ClaimsTransformation Id="CreateQrCodeUri" TransformationMethod="BuildUri">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="totpLabel" TransformationClaimType="label" />
        <InputClaim ClaimTypeReferenceId="secretKey" TransformationClaimType="secret" />
        <InputClaim ClaimTypeReferenceId="totpIssuer" TransformationClaimType="issuer" />
      </InputClaims>
      <InputParameters>
        <InputParameter Id="scheme" DataType="string"Value="otpauth" />
        <InputParameter Id="path" DataType="string" Value="totp" />
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="qrCodeContent"TransformationClaimType="outputClaim" />
      </OutputClaims>
    </ClaimsTransformation>