Using nested JSON in a REST API call with Azure AD B2C

Image: The word “JSON”

There are two good references for this: here and here.

As usual, we use Beeceptor and the gist of the custom policy is here.

The Beeceptor API is:

Image of Beeceptor showing JSON detailed below.

The input to the API is:

{ 
"id": "12345678",
"group":{
"role":"Admin",
"branch": "Main"
}
}

and the output is:

{
"id": "12345678",
"firstName": "Joe",
"lastName": "Bloggs",
"birthday": "02-02-1980",
"email": "joeb@company.com",
"contacts": {
"mobile":{
"countryCode": "64",
"mobileNumber": "27123456"
},
"office":{
"countryCode": "64",
"officeNumber": "09123456"
},
},
"username": "joeb"
}

In both cases, there is nested JSON.

The claims transformation for the input is below.

<ClaimsTransformation Id="GenerateIdentityRequestBody" TransformationMethod="GenerateJson">
<!-- <InputClaims> -->
<!-- <InputClaim ClaimTypeReferenceId="id" TransformationClaimType="inputClaim"/> -->
<!-- </InputClaims> -->
<InputParameters>
<InputParameter Id="id" DataType="string" Value="12345678"/>
<InputParameter Id="group.role" DataType="string" Value="Admin"/>
<InputParameter Id="group.branch" DataType="string" Value="Main"/>
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="requestBody" TransformationClaimType="outputClaim"/>
</OutputClaims>
</ClaimsTransformation>

Notice you use “InputClaim” for variables and “InputParameter” for constants. I’ve just made “id” a constant for simplicity but normally it would be a variable and the code required is the piece that’s commented out.

The nesting is accomplished by using:

"group.role"

The actual API is:

<TechnicalProfile Id="REST-Identity-API">
<DisplayName>Test Customer Identity API</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
<Metadata>
<Item Key="ServiceUrl">https://xxx.free.beeceptor.com/yyy</Item>
<Item Key="SendClaimsIn">Body</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="AllowInsecureAuthInProduction">false</Item>
<Item Key="ResolveJsonPathsInJsonTokens">true</Item>
<Item Key="ClaimUsedForRequestPayload">requestBody</Item>

</Metadata>
<InputClaimsTransformations>
<InputClaimsTransformation ReferenceId="GenerateIdentityRequestBody"/>
</InputClaimsTransformations>
<InputClaims>
<InputClaim ClaimTypeReferenceId="requestBody"/>
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="id"/>
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName"/>
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="familyName"/>
<OutputClaim ClaimTypeReferenceId="extension_dobirth" PartnerClaimType="birthday"/>
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email"/>
<OutputClaim ClaimTypeReferenceId="countryCode" PartnerClaimType="contacts.mobile.countryCode"/>
<OutputClaim ClaimTypeReferenceId="mobileNumber" PartnerClaimType="contacts.mobile.mobileNumber"/>
<OutputClaim ClaimTypeReferenceId="countryCode" PartnerClaimType="contacts.office.countryCode"/>
<OutputClaim ClaimTypeReferenceId="officeNumber" PartnerClaimType="contacts.office.officeNumber"/>
<OutputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username"/>
<OutputClaim ClaimTypeReferenceId="objectId" DefaultValue="123456ABCDEF" AlwaysUseDefaultValue="true"/>
</OutputClaims>
</TechnicalProfile>

I have highlighted the important parts. You call the claims transformation to build the input and use “requestBody” to contain the JSON. Notice the metadata commands that you need to use.

Again the nesting is accomplished by:

"contacts.mobile.countryCode"

The output is:

Image showing claims returned e.g. “id” = “12345678” and “given_name” = “Joe”

You can see the attributes match the API response.

Because this is just a test policy, I’ve constructed the objectId manually that is used for the “sub” field.

I don’t know if there is a way to put the actual JSON string into the output claims. Basically, the output claims are a flat structure.

All good!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Rory Braybrook

Rory Braybrook

NZ Microsoft Identity dude and MVP. Azure AD/B2C/ADFS/Auth0/identityserver. StackOverflow: https://bit.ly/2XU4yvJ Presentations: http://bit.ly/334ZPt5