In this post, let's see how we can include EmployeeId in Azure AD B2C User Profile in Claims for an Azure AD B2C Sign-In
(it could be any actually) UserJourney.
|
AAD B2C User Profile - Employee ID
|
Unfortunately,
AAD-UserReadUsingObjectId technical profile only retrieves the basic User Profile information
and
EmployeeId is not part of it (Read
User profile attributes).
So in order to retrieve these additional properties what we need to do is
update our
UserJourney by adding another
OrchestrationStep to retrieve users'
EmployeeId by calling Microsoft Graph API. But an important thing to note here is,
users cannot obtain tokens for Microsoft Graph API using delegated permissions
(Read
Working with MSAL.js and Azure AD B2C).
In that case, we can create a simple Minimal API or a HttpTriggered Azure
Function that accepts users'
ObjecteId and from there, call Microsoft Graph API using Client-Credentials and
retrieve the users'
EmployeeId. You can have a look at
this Minimal API for an example on how to call Graph API using Client-Credentials
For simplicity, let's say we have the following endpoint.
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
WebApplication app = builder.Build();
app.UseHttpsRedirection();
app.MapPost("/claims", (GetClaimsRequest getClaimsRequest) =>
{
// TODO: Get claims for the user by calling Graph API using ClientCredentials
return new
{
employeeId = "EMP101"
};
});
app.Run();
public class GetClaimsRequest
{
public string ObjectId { get; set; }
}
Now the first thing to do is modify our B2C_1A_TrustFrameworkExtensions and define a ClaimType for employeeId.
<ClaimsSchema>
...
<ClaimType Id="employeeId">
<DisplayName>Employee Id</DisplayName>
<DataType>string</DataType>
</ClaimType>
</ClaimsSchema>
And then register a Restful ClaimsProvider to call our REST endpoint and pass the objectId.
<ClaimsProviders>
...
<ClaimsProvider>
<DisplayName>Get Additional Claims via REST</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="REST-GetAdditionalClaims">
<DisplayName>Get Additional Claims via REST call and transform claims</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://743q57pk-7047.aue.devtunnels.ms/claims</Item>
<Item Key="SendClaimsIn">Body</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="AllowInsecureAuthInProduction">true</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="employeeId" PartnerClaimType="employeeId"/>
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
</ClaimsProviders>
Here, I am mapping the employeeId that is being returned from the API to ClaimTypeReferenceId="employeeId" that we created before.
The last step is to modify our UserJourney and add an OrchestrationStep to call the REST endpoint before sending the claims.
<OrchestrationSteps>
...
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="RESTGetAdditionalClaims" TechnicalProfileReferenceId="REST-GetAdditionalClaims" />
</ClaimsExchanges>
</OrchestrationStep>
...
</OrchestrationSteps>
And that's about it. In my example, I am using SAML authentication, and I can
see employeeId is now included in the SAML response.
|
EmployeeId Included In Claims
|
And that's about it.
Hope this helps.
Happy Coding.
Regards,
Jaliya