2

I'm using Microsoft Graph API to set a custom value (string) on a user. I've tried using both open & directory extensions to store the data and both seem to work fine in the API level as I'm able to get the data back on a user.

What I'm trying to do next is to get the value of this extension into a B2C custom policy claim. I haven't been able to find any documentation that shows how to get an open extension's value in a custom policy even though the docs state it is supported so I've tried doing it with a directory extension.

The extension's name is extension_{appId}_myString and was created through this HTTP call:

POST https://graph.microsoft.com/v1.0/applications/graph-app-object-id/extensionProperties

{
    "name": "myString",
    "dataType": "String",
    "targetObjects": [
        "User"
    ]
}

I've added the claim type definition as follows:

<ClaimType Id="myString">
    <DisplayName>This is my string</DisplayName>
    <DataType>string</DataType>
    <DefaultPartnerClaimTypes>
        <Protocol Name="OpenIdConnect" PartnerClaimType="extension_myString" />
        <Protocol Name="OAuth2" PartnerClaimType="extension_myString" />
    </DefaultPartnerClaimTypes>
</ClaimType>

My user journey definition:

<UserJourney Id="SignIn">
    <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.selfasserted">
            <ClaimsProviderSelections>
                <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninExchange" />
            </ClaimsProviderSelections>
            <ClaimsExchanges>
                 <ClaimsExchange Id="LocalAccountSigninExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingID" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
    </OrchestrationSteps>
    <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>

I've added this output claim in the technical profiles of steps 1 & 2:

<OutputClaim ClaimTypeReferenceId="myString" PartnerClaimType="extension_myString" />

My AAD-Common technical profile has the b2c-extensions-app client ID & object ID metadata items and I'm able to successfully complete the authentication process and get to the JWT screen but my extension's value isn't shown there.

I don't understand if I did something wrong or just missed another place in which the custom claim should be added in order for it to be shown in the token. Is there some kind of way to "print" the value of the claim to see if it's present in the policy's runtime? At least I know the value is there and I only need to put it in the token..

One more thing that I'm not sure of is the creation of the extension value through Graph API. I've used the graph application's credentials to get the Graph API token and also used it's object ID to create the directory extension on the user object. On the other hand, there's the b2c-extensions-app which is the app that queries the data during the custom policy's runtime. From my understanding both apps work against the same Active Directory instance so it shouldn't be a problem but maybe I misunderstood something.

Danny Idlis
  • 43
  • 1
  • 6

2 Answers2

2

You can’t. Open extensions are supported by MS Graph API. B2C policy uses AAD Graph behind the scenes, it can only fetch the old extension attribute type. To fetch an open extension, you’d have to call your own api, which in turn calls MS Graph API to fetch this open extension.

Instead of using an open extension use the older type:

https://learn.microsoft.com/en-us/azure/active-directory-b2c/microsoft-graph-operations#application-extension-directory-extension-properties

https://learn.microsoft.com/en-us/graph/api/resources/extensionproperty?view=graph-rest-1.0

Jas Suri - MSFT
  • 10,605
  • 2
  • 10
  • 20
  • This makes sense now! I just need to figure out why I'm not able to read the directory extension and see it in the token.. Do you have any idea what am I missing? – Danny Idlis Nov 21 '22 at 11:23
  • 1
    Your policy logic is fine, the only thing it might be is that you must create the extension under the same AppId/objectId as what you put in AAD-Common. Also get rid of DefaultPartnerClaimTypes in the Claim Definition – Jas Suri - MSFT Nov 22 '22 at 11:15
  • It works, thank you so much! The only thing that's weird is that if I update the extension through MS Graph API and run the policy right after I receive a 204 status - the policy still returns the old value even though it was already successfully updated. Is there some kind of syncing mechanism behind the scenes? Because I expect the new value to be reflected immediately.. – Danny Idlis Nov 22 '22 at 14:03
  • It’s replicated through many DCs over a minute. If you hit a different DC to where you made the update, you will get the old value back. The behaviour is expected. – Jas Suri - MSFT Nov 22 '22 at 21:03
0

For configuring a custom claim in Azure B2C custom profile, as per https://learn.microsoft.com/en-us/azure/active-directory-b2c/user-flow-custom-attributes?pivots=b2c-custom-policy#create-a-custom-attribute-through-azure-portal, you must prefix the claim type ID with extension_ to allow the correct data mapping

enter image description here

  • Within Claims Schema the claim should be defined as:

enter image description here

  • The following example demonstrates the use of a custom attribute in Azure AD B2C custom policy in a technical profile, input, output, and persisted claims.

enter image description here

Thanks

Mavric20
  • 96
  • 3
  • I've also tried this but without any success. I think it has something to do with how I created the directory extension through the Graph API.. There are also no docs whatsoever on how to get open extensions' values even though it should be supported: https://learn.microsoft.com/en-us/graph/extensibility-overview?tabs=http#choose-an-extension-type-for-your-application – Danny Idlis Nov 20 '22 at 16:21
  • Did you add an output claim to the relying party section too? – Jas Suri - MSFT Nov 21 '22 at 09:41
  • Yes, under the relying party tag I have a technical profile called PolicyProfile and it's OutputClaims contain the tag – Danny Idlis Nov 21 '22 at 09:55