Blog Post

Apps on Azure Blog
6 MIN READ

Basic understanding on Microsoft Entra custom claims provider

theringe's avatar
theringe
Icon for Microsoft rankMicrosoft
May 06, 2024

TOC

  1. What is it
  2. Architecture
  3. How to use it
  4. 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:

  1. User login to the Application
  2. 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.
  3. The Custom claims provider asking our own system (e.g., a Function App) for the claims (e.g., criminal record) related to that user.
  4. Our system get the related claims (e.g., by querying DB) and return it to the Custom claims provider.
  5. 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

  1. Open VSCode.
  2. Create a new folder for your project (e.g., ccp-func)
  3. Under the Workspace bar, select the Azure Functions icon > Create New Project.
  4. Select C# as the language, and .NET 6.0 LTS as the .NET runtime.
  5. Select HTTP trigger as the template.
  6. Provide a name for the trigger (e.g., AuthEventsTrigger)
  7. Accept Company.Function as the namespace, with AccessRights set to Function.
  8. 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

  1. Open the *.csproj file, change the AuthenticationEvents version to "1.0.0-beta.6"

  1. 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);
	            }
	        }
	    }
	}

 

 

  1. 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.
  2. Publish the project to the Function App
  3. On Azure Portal, go to that Function App and onTokenIssuanceStart trigger, copy the Function URL for further use.

Format: https://xxx.azurewebsites.net/runtime/webhooks/customauthenticationextension?functionName=onTokenIssuanceStart&code=XXX

 

B-1: Register a custom authentication extension

  1. In Azure Portal, go to Microsoft Entra ID and select Enterprise applications.
  2. Select Custom authentication extensions, and then select Create a custom extension.
  3. In Basics, select the TokenIssuanceStart event type and select Next.
  4. 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.

  1. 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.

  1. 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

  1. Select Next, then Create.
  2. Note the App ID under API Authentication, which is needed for setting environment variables in your Azure Function app.

  1. Under API Authentication, select Grant permission.
  2. 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

  1. In Azure Portal, go to Microsoft Entra ID and select App registrations.
  2. Select New registration.
  3. 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.

  1. Copy Application ID and Tenant ID for further use.

  1. 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.

  1. 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

  1. In Azure Portal, go to Microsoft Entra ID and select Enterprise applications.
  2. 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.

  1. 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.

  1. Repeat this process to add the customClaimsProvider.customRoles, customClaimsProvider.apiVersion and customClaimsProvider.correlationId attributes, and the corresponding name.

 

A-4: Protect your Azure Function

  1. In Azure Portal, go to the Function App
  2. Under Settings, select Authentication.
  3. Select Add Identity provider.
  4. 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

  1. 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

  1. We could have a test on the whole process, open a browser and visit the following URL

https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize?client_id={App_to_enrich_ID}&response_type=id_token&redirect_uri=https://jwt.ms&scope=openid&state=12345&nonce=12345

{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

  1. 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

Create a REST API with a token issuance start event for Azure Functions (preview) - Microsoft identity platform | Microsoft Learn

Custom claims provider: Configure a token issuance event - Microsoft identity platform | Microsoft Learn

Authentication events trigger for Azure Functions client library for .NET - Azure for .NET Developers | Microsoft Learn

 

 

Updated May 09, 2024
Version 3.0
  • Fazer01 Hello sir, thank you for asking.

     

    The Function App in A-4 is the same mentioned in A-1 to A-3, there is only one Function App after all.

     

    The reason why the steps are classified as A/B/C is because each of them represents settings that need to be configured in different resources. Please refer to the image at the top of this article for corresponding markings:

     

    A = Function App

    B = Enterprise Application (custom claim provider)

    C = App Registration

     

    hope it helps 🙂

  • Fazer01's avatar
    Fazer01
    Copper Contributor

    Hi there!

     

    Nice article. However, I have a question. (A-4 -> step 1, you mention "the function app"). What functionapp is mentioned by "the functionapp"? Is this the Authentication Function API (the one that adds the custom claims? Or another (new) function app?

     

    Regards,