DEV Community

Cover image for Develop integrated solutions with Active Directory B2C and Azure Event Grid.
Nicola Biancolini
Nicola Biancolini

Posted on • Edited on • Originally published at binick.github.io

Develop integrated solutions with Active Directory B2C and Azure Event Grid.

We will see how it is possible to create a solution that integrates Azure Active Directory B2C to save on Blob Storage dummy data at user registration.

Solution overview.

The solution is composed as follows:

Component map

  • read-customer-details-identity-la: represents the API whose purpose is to retrieve the content of the blob from customersstgacc (the storage account)
  • customer-register-tpc: is the topic in which are collected the events of the creation of a new user
  • customer-identity-details-filler-la: it represents the API that is in charge of generating fictitious data that will be saved inside a blob on the customersstgacc steps
  • contoso-b2c: is the access and identity management service offered by Azure

Introduction to Azure Event Grid.

In Azure there is an implementation of the publish/subscribe pattern designed to facilitate integration and resource management via an event-driven development paradigm.

Through the Event Grid will be possible to subscribe to built-in message sources via a set of handlers.

If this is not enough, it is possible to create custom _topics to which you can subscribe to receive events.

Creating a custom topic.

You can refer to this guide to create a topic.

One choice to make when creating the topic concerns the scheme of the HTTP request content used. Currently, supported schemas are:

The message used in this case has the following structure

[
    {
        "data": {
            "objectId": "25100647-0dcc-4571-b7b4-b03e4ce72d02" // unique user identifier
        },
        "id": "25100647-0dcc-4571-b7b4-b03e4ce72d02", // unique message identifier, the same of `data.objectId` in this case
        "eventType": "Microsoft.ActiveDirectory", 
        "subject": "contosob2cqtofmpm.onmicrosoft.com",
        "dataVersion": "1.0",
        "metadataVersion": "1",
        "eventTime": "2021-12-03T21:04:03.8504745Z",
        "topic": "/subscriptions/{your-subscription-id}/resourceGroups/{your-resource-group}/providers/Microsoft.EventGrid/topics/{your-event-grid-topic}"
    }
]
Enter fullscreen mode Exit fullscreen mode

Issuing the registration event.

Sending events to the topic is done using a RESTful technical profile.

<TechnicalProfile Id="AAD-UserEmitRegistrationEvent">
    <DisplayName>Emit user registration event to Event Grid.</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
        <Item Key="ServiceUrl">{Settings:CustomerRegisteredTopicUrl}</Item>
        <Item Key="AuthenticationType">ApiKeyHeader</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="ClaimUsedForRequestPayload">userRegisterEvent</Item>
        <Item Key="DefaultUserMessageIfRequestFailed">Cannot process your request right now, please try again later.</Item>
    </Metadata>
    <CryptographicKeys>
        <Key Id="aeg-sas-key" StorageReferenceId="B2C_1A_CustomerRegisteredTopicSas" />
    </CryptographicKeys>
    <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GetSystemDateTime" />
        <InputClaimsTransformation ReferenceId="GenerateRegistrationEventRequest" />
    </InputClaimsTransformations>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="userRegisterEvent" />
    </InputClaims>
    <PersistedClaims>
        <PersistedClaim ClaimTypeReferenceId="systemDateTime" />
    </PersistedClaims>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>
Enter fullscreen mode Exit fullscreen mode

This fragment of markup translated into curl command, for more explicability, would look like this:

curl -X POST -H "aeg-sas-key: $key" -d "$event" $endpoint
Enter fullscreen mode Exit fullscreen mode

where the authentication requirements are met by the AuthenticationType metadata to which is associated the cryptographic key aeg-sas-key whose value is retrieved from the key B2C_1A_CustomerRegisteredTopicSas present in the collection of policy keys.

"TL;DR"
The choice of the topic template in this example was guided by the limitations currently imposed by the RESTful technical profile regarding the possibilities of building the HTTP request, in fact for a combination of criteria it is not possible to pass information in the headers and the body of the request at the same time.

This makes it impossible to send towards a topic schemes of type Cloud Event since the protocol, in version 1.0 requires the presence of a mandatory header.

Much more complex is the creation of the body of the request for which it is necessary:

  • use the InputClaimsTransformation
  • add two statements inside the baggage userRegisterEvent and systemDateTime both of type string.

Finally, the technical profile has been added among the technical validation profiles of LocalAccountSignUpWithLogonEmail so that the event is issued only when a user is registered.

Using claim transformations.

During the creation of custom criteria we could have the necessity to execute calculations, as the number of attempts of authentication, that even if very simple would result impossible without the execution of functions.

This requirement finds expressivity through the ClaimsTransformation whose reference of the transformations of the claims contains the complete list of the transformations usable.

In the example the methods GetCurrentDateTime and GenerateJson were used

<ClaimsTransformation Id="GetSystemDateTime" TransformationMethod="GetCurrentDateTime">
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="systemDateTime" TransformationClaimType="currentDateTime" />
    </OutputClaims>
</ClaimsTransformation>
Enter fullscreen mode Exit fullscreen mode

The purpose of GetSystemDateTime is to enhance the systemDateTime claim.

<ClaimsTransformation Id="GenerateRegistrationEventRequest" TransformationMethod="GenerateJson">
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="0.data.objectId" />
        <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="0.id" />
        <InputClaim ClaimTypeReferenceId="systemDateTime" TransformationClaimType="0.eventTime" />
    </InputClaims>
    <InputParameters>
        <InputParameter Id="0.dataVersion" DataType="string" Value="1.0" />
        <InputParameter Id="0.eventType" DataType="string" Value="Microsoft.ActiveDirectory" />
        <InputParameter Id="0.subject" DataType="string" Value="{Settings:Tenant}" />
    </InputParameters>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="userRegisterEvent" TransformationClaimType="outputClaim" />
    </OutputClaims>
</ClaimsTransformation>
Enter fullscreen mode Exit fullscreen mode

GenerateRegistrationEventRequest has instead the burden of constructing the JSON and enhancing the userRegisterEvent claim.

Conclusions.

In this article, we have seen how through Identity Experience Framework it is possible to integrate a B2C tenant with our infrastructure and open possible interesting development scenarios.

To do this we touched on Azure Event Grid and how to create an Event Grid Topic.

Finally how you can manipulate attestations and use them within technical profiles.

If you are interested in the complete example you can find it at https://github.com/binick/samples/tree/master/src/enrich-a-jwt-token-with-ief.

Top comments (0)