Craig Martin
Craig Martin

Reputation: 169

Azure B2C Custom Policy - Output Claim 'role' is not supported in Azure Active Directory Provider technical profile

In Azure, I've changed from using the standard attributes and user flows to using custom policies as I need to be able to attach the user's "role" to the JWT token.

To attach the "role", I need to call an Azure Function which performs some logic to work this out.

TrustFrameworkBase.xml and TrustFrameworkExtensions.xml both upload fine, but when I upload SignUpOrSignin.xml I get the following validation error:

Validation failed: 1 validation error(s) found in policy "B2C_1A_SIGNUP_SIGNIN" of tenant "mytenant.onmicrosoft.com".Output Claim 'role' is not supported in Azure Active Directory Provider technical profile 'AzureFunctions-WebHook' of policy 'B2C_1A_signup_signin'. If it is a claim with default value, add AlwaysUseDefaultValue="true" to the output claim mapping.

I've been following this Microsoft tutorial, and can't see what I have done different for it not to work. https://learn.microsoft.com/en-us/azure/active-directory-b2c/add-api-connector-token-enrichment?pivots=b2c-custom-policy.

TrustFrameworkExtensions.xml (relevant code)

<BuildingBlocks>
<ClaimsSchema>
  <ClaimType Id="role">
    <DisplayName>Role</DisplayName>
    <DataType>string</DataType>
  </ClaimType>
</ClaimsSchema>
<ClaimsProvider>
      <DisplayName>REST APIs</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="AzureFunctions-WebHook">
          <DisplayName>Azure Function Web Hook</DisplayName>
          <Protocol Name="Proprietary"
            Handler="Web.TPEngine.Providers.AzureActiveDirectoryProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <Item Key="ServiceUrl">
              https://*.azurewebsites.net/api/*</Item>
            <Item Key="SendClaimsIn">Body</Item>
            <!-- Set AuthenticationType to Basic or ClientCertificate in production environments -->
            <Item Key="AuthenticationType">None</Item>
            <!-- REMOVE the following line in production environments -->
            <Item Key="AllowInsecureAuthInProduction">true</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
          </InputClaims>
          <OutputClaims>
            <!-- Claims parsed from your REST API -->
            <OutputClaim ClaimTypeReferenceId="role" />
          </OutputClaims>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
<OrchestrationStep Order="7" Type="ClaimsExchange">
   <ClaimsExchanges>
       <ClaimsExchange Id="*"
             TechnicalProfileReferenceId="AzureFunctions-WebHook" />
       </ClaimsExchanges>
</OrchestrationStep>

<OrchestrationStep Order="8" Type="SendClaims"
     CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

SignUpSignin.xml (relevant code)

<RelyingParty>
    <DefaultUserJourney ReferenceId="SignUpOrSignIn" />
    <!-- <Endpoints>
      points to refresh token journey when app makes refresh token request
      <Endpoint Id="Token" UserJourneyReferenceId="RedeemRefreshToken" />
    </Endpoints> -->
    <TechnicalProfile Id="PolicyProfile">
      <DisplayName>PolicyProfile</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="displayName" />
        <OutputClaim ClaimTypeReferenceId="givenName" />
        <OutputClaim ClaimTypeReferenceId="surname" />
        <OutputClaim ClaimTypeReferenceId="email" />
        <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="emails" />
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
        <OutputClaim ClaimTypeReferenceId="identityProvider" />
        <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
        <OutputClaim ClaimTypeReferenceId="role" />
      </OutputClaims>
      <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
  </RelyingParty>

(I've already found this similar question: Why are claims being flagged as not supported in my custom policy?, but I have somewhat struggled with the answers.)

(templates used: https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/tree/main/SocialAndLocalAccounts)

Upvotes: 0

Views: 1003

Answers (1)

rbrayb
rbrayb

Reputation: 46773

Sample has for REST API:

Handler="Web.TPEngine.Providers.RestfulProvider

You have:

Handler="Web.TPEngine.Providers.AzureActiveDirectoryProvider

role is not an allowed attribute in the B2C schema.

Upvotes: 1

Related Questions