TOC
- What is it
- Architecture
- How to use it
- References
What is it
When a user authenticates to an app (e.g., MS Entra ID application), a custom claims provider can be used to add claims into the token. A custom claims provider is made up of a custom authentication extension that calls an external REST API (e.g., a Function App), to fetch claims from external systems (e.g., a Database). A custom claims provider can be assigned to one or many applications.
Claim: Please imagine it as features (or attributes) that belong to the end user. As it may involve sensitive information within the enterprise, the enterprise owner wishes to store this user information in the on-premises environment, while also hoping to retrieve and utilize it through the authentication process.
This service is suitable for the following scenarios:
1) It can be used as a transition for gradually migrating on-premises Active Directory to Microsoft Azure AD.
2) When user-sensitive information needs to be stored in an on-premises environment for various reasons.
Architecture
Procedure:
- User login to the Application
- If this AAD includes a custom claims provider, then the relevant features need to be obtained from the custom claims provider before generating the token.
- The Custom claims provider asking our own system (e.g., a Function App) for the claims (e.g., criminal record) related to that user.
- Our system get the related claims (e.g., by querying DB) and return it to the Custom claims provider.
- The custom claims provider packages the default user information along with the additionally obtained claims, encodes them into a token, and returns it to the user.
How to use it
A-1: Create a Function App from Azure portal
Choose ".NET 6 (LTS), in-process model" as the runtime and "Windows" as the OS.
A-2: Setup a local project via VSCode
- Open VSCode.
- Create a new folder for your project (e.g., ccp-func)
- Under the Workspace bar, select the Azure Functions icon > Create New Project.
- Select C# as the language, and .NET 6.0 LTS as the .NET runtime.
- Select HTTP trigger as the template.
- Provide a name for the trigger (e.g., AuthEventsTrigger)
- Accept Company.Function as the namespace, with AccessRights set to Function.
- Open the terminal, navigate to the project folder and enter the following:
dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents --prerelease
A-3: Add/Modify the sample code
- Open the *.csproj file, change the AuthenticationEvents version to "1.0.0-beta.6"
- Open the AuthEventsTrigger.cs file, copy and paste the following code to replace
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart.Actions;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
namespace AuthEventTrigger
{
public static class Function1
{
[FunctionName("onTokenIssuanceStart")]
public static AuthenticationEventResponse Run(
[AuthenticationEventsTrigger(AudienceAppId = "TBA",
AuthorityUrl = "https://login.microsoftonline.com/TBA",
AuthorizedPartyAppId = "99045fe1-7639-4a75-9d4a-577b6ca3810f")]TokenIssuanceStartRequest request, ILogger log)
{
try
{
if (request.RequestStatus == RequestStatusType.Successful)
{
request.Response.Actions.Add(new ProvideClaimsForToken(
new TokenClaim("dateOfBirth", "01/01/2000"),
new TokenClaim("customRoles", "Writer", "Editor"),
new TokenClaim("apiVersion", "1.0.0"),
new TokenClaim("correlationId", request.Data.AuthenticationContext.CorrelationId.ToString())
));
}
else
{
log.LogInformation(request.StatusMessage);
}
return request.Completed();
}
catch (Exception ex)
{
return request.Failed(ex);
}
}
}
}
- As you can see that there are two instances of "TBA" in the code, indicating that some of the configuration content needs to be acquired in subsequent operations. Therefore, we will maintain this status for now.
- Publish the project to the Function App
- On Azure Portal, go to that Function App and onTokenIssuanceStart trigger, copy the Function URL for further use.
B-1: Register a custom authentication extension
- In Azure Portal, go to Microsoft Entra ID and select Enterprise applications.
- Select Custom authentication extensions, and then select Create a custom extension.
- In Basics, select the TokenIssuanceStart event type and select Next.
- In Endpoint Configuration, fill in the following properties:
Name: (e.g., CCP Token issuance event)
Target Url: The URL you've get from A-3 step 5.
Select Next.
- In API Authentication, select the Create new app registration option to create an app registration that represents your function app.
Give the app a name (e.g., CCP Azure Functions authentication events API)
Select Next.
- In Claims, enter the attributes (Claims) that you expect your custom authentication extension to parse from your REST API and will be merged into the token. Add the following claims:
dateOfBirth
customRoles
apiVersion
correlationId
- Select Next, then Create.
- Note the App ID under API Authentication, which is needed for setting environment variables in your Azure Function app.
- Under API Authentication, select Grant permission.
- A new window opens, and once signed in, it requests permissions to receive custom authentication extension HTTP requests. This allows the custom authentication extension to authenticate to your API. Select Accept.
C-1: Configure an App to receive enriched tokens
- In Azure Portal, go to Microsoft Entra ID and select App registrations.
- Select New registration.
- Enter a Name for the application (e.g., CCP test application)
Under Supported account types, select Accounts in this organizational directory only.
In the Select a platform dropdown in Redirect URI, select Web and then enter https://jwt.ms in the URL text box.
Select Register to complete the app registration.
- Copy Application ID and Tenant ID for further use.
- Back to the app in Azure portal, go to Manage, select Authentication.
Under Implicit grant and hybrid flows, select the ID tokens (used for implicit and hybrid flows) checkbox.
Select Save.
- Back to the app in Azure portal, go to Manage, select Manifest.
Set the acceptMappedClaims to true.
Set the accessTokenAcceptedVersion to 2.
Select Save to save the changes.
B-2: Assign a custom claims provider to your app
- In Azure Portal, go to Microsoft Entra ID and select Enterprise applications.
- Under Manage, select All applications. Find and select (e.g., CCP test application) from the list.
From the Overview page, navigate to Manage, and select Single sign-on.
Under Attributes & Claims, select Edit.
Expand the Advanced settings menu.
Next to Custom claims provider, select Configure.
Expand the Custom claims provider drop-down box, and select the (e.g., CCP Token issuance event) you created earlier.
Select Save.
- Next, assign the attributes from the custom claims provider, which should be issued into the token as claims:
Select Add new claim to add a new claim. Provide a name to the claim you want to be issued, for example dateOfBirth.
Under Source, select Attribute, and choose customClaimsProvider.dateOfBirth from the Source attribute drop-down box.
- Repeat this process to add the customClaimsProvider.customRoles, customClaimsProvider.apiVersion and customClaimsProvider.correlationId attributes, and the corresponding name.
A-4: Protect your Azure Function
- In Azure Portal, go to the Function App
- Under Settings, select Authentication.
- Select Add Identity provider.
- Select Microsoft as the identity provider.
Select Workforce configuration (current tenant).
Under App registration select Pick an existing app registration in this directory for the App registration type, and pick the (e.g., CCP Azure Functions authentication events API).
Enter the following issuer URL, https://login.microsoftonline.com/{tenantId}/v2.0, where {tenantId} is the tenant ID you've get from C-1 step 4.
Under Client application requirement, select Allow requests from specific client applications, in Allowed client applications click edit button and add 2 app ids (The id you've get from B-1 step 8 and a fixed one 99045fe1-7639-4a75-9d4a-577b6ca3810f).
Under Identity requirement, select Allow requests from any identity.
Under Tenant requirement, select Use default restrictions based on issuer.
Under Unauthenticated requests, select HTTP 401 Unauthorized as the identity provider.
Unselect the Token store option.
Select Add to add authentication to your Azure Function.
A-5: Modify the sample code
- We have noticed that there are 2 TBA in the code and already know what is the related value. So we could deploy it again to the Function App.
B-3: Test
- We could have a test on the whole process, open a browser and visit the following URL
{tenantId} stands for the Tenant ID you've get from C-1 step 4
{App_to_enrich_ID} stands for the Application ID you've get from C-1 step 4
- After the login we could see the result, which the returned token containing the related claims
References
Custom claims provider overview - Microsoft identity platform | Microsoft Learn