Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents 1.0.0-beta.6

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
This is a prerelease version of Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents --version 1.0.0-beta.6
NuGet\Install-Package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents -Version 1.0.0-beta.6
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents" Version="1.0.0-beta.6" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents --version 1.0.0-beta.6
#r "nuget: Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents, 1.0.0-beta.6"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents as a Cake Addin
#addin nuget:?package=Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents&version=1.0.0-beta.6&prerelease

// Install Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents as a Cake Tool
#tool nuget:?package=Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents&version=1.0.0-beta.6&prerelease

Authentication events trigger for Azure Functions client library for .NET

The authentication events trigger for Azure Functions allows you to implement a custom extension to handle Microsoft Entra authentication events. The authentication events trigger handles all the backend processing for incoming HTTP requests for Microsoft Entra authentication events and provides the developer with:

  • Token validation for securing the API call
  • Object model, typing, and IDE intellisense
  • Inbound and outbound validation of the API request and response schemas

Getting started

Install the package

Install the authentication events trigger for Azure Functions with NuGet:

dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents --prerelease

Prerequisites

Authenticate the client

When the Microsoft Entra authentication events service calls your custom extension, it sends an Authorization header with a Bearer {token}. This token represents a service to service authentication in which:

  • The 'resource', also known as the audience, is the application that you register to represent your API. This is represented by the aud claim in the token.
  • The 'client' is a Microsoft application that represents the Microsoft Entra authentication events service. It has an appId value of 99045fe1-7639-4a75-9d4a-577b6ca3810f. This is represented by:
    • The azp claim in the token if your application accessTokenAcceptedVersion property is set to 2.
    • The appid claim in the token if your resource application's accessTokenAcceptedVersion property is set to 1 or null.

There are three approaches to authenticating HTTP requests to your function app and validating the token.

Validate tokens using Azure Functions Microsoft Entra ID authentication integration

When running your function in production, it is highly recommended to use the Azure Functions Microsoft Entra ID authentication integration for validating incoming tokens. Set the following function application settings.

  1. Go to the "Authentication" tab in your Function App
  2. Click on "Add identity provider"
  3. Select "Microsoft" as the identity provider
  4. Select "Provide the details of an existing app registration"
  5. Enter the Application ID of the app that represents your API in Microsoft Entra ID

The issuer and allowed audience depends on the accessTokenAcceptedVersion property of your application (can be found in the "Manifest" of the application).

If the accessTokenAcceptedVersion property is set to 2: 6. Set the Issuer URL to "https://login.microsoftonline.com/{tenantId}/v2.0" 7. Set an 'Allowed Audience' to the Application ID (appId`)

If the accessTokenAcceptedVersion property is set to 1 or null: 6. Set the Issuer URL to "https://sts.windows.net/{tenantId}/" 7. Set an 'Allowed Audience' to the Application ID URI (also known asidentifierUri). It should be in the format ofapi://{azureFunctionAppName}.azurewebsites.net/{resourceApiAppId}orapi://{FunctionAppFullyQualifiedDomainName}/{resourceApiAppId}` if using a custom domain name.

By default, the Authentication event trigger will validate that Azure Function authentication integration is configured and it will check that the client in the token is set to 99045fe1-7639-4a75-9d4a-577b6ca3810f (via the azp or appid claims in the token).

If you want to test your API against some other client that is not Microsoft Entra authentication events service, like using Postman, you can configure an optional application setting:

  • AuthenticationEvents__CustomCallerAppId - the guid of your desired client. If not provided, 99045fe1-7639-4a75-9d4a-577b6ca3810f is assumed.
Have the trigger validate the token

In local environments or environments that aren't hosted in the Azure Function service, the trigger can do the token validation. Set the following application settings in the local.settings.json file:

  • AuthenticationEvents__TenantId - your tenant ID
  • AuthenticationEvents__AudienceAppId - the same value as "Allowed audience" in option 1.
  • AuthenticationEvents__CustomCallerAppId (optional) - the guid of your desired client. If not provided, 99045fe1-7639-4a75-9d4a-577b6ca3810f is assumed.

An example local.settings.json file:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "AuthenticationEvents__TenantId": "8615397b-****-****-****-********06c8",
    "AuthenticationEvents__AudienceAppId": "api://46f98993-****-****-****-********0038",
    "AuthenticationEvents__CustomCallerAppId": "46f98993-****-****-****-********0038"
  }
}
No token validation

If you would like to not authenticate the token while in local development, set the following application settings in the local.settings.json file:

  • AuthenticationEvents__BypassTokenValidation - value of true will make the trigger not check for a validation of the token.

Quickstart

  • Visual Studio 2019

    • Start Visual Studio
    • Select "Create a new project"
    • In the template search area search and select "AzureAuthEventsTrigger"
    • Give your project a meaningful Project Name, Location, Solution and Solution Name.
  • Visual Studio Code

    • Start Visual Studio Code
    • Run the command "Create Azure Authentication Events Trigger Project" via the command palette
    • Follow the project creation prompts
  • Please note: that on a first time run it might take awhile to download the the required packages.

  • For development purpose turn of token validation for testing:

  • Add the AuthenticationEvents__BypassTokenValidation application key to the "Values" section in the local.settings.json file and set it's value to true. If you do not have a local.settings.json file in your local environment, create one in the root of your Function App.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "AuthenticationEvents__BypassTokenValidation": true
  }
}
  • Once the project is loaded, you can run the sample code and you should see the Azure functions developer's application load your end point.

Key concepts

.NET SDK

Key concepts of the Azure .NET SDK can be found here.

Microsoft Entra custom extensions

Custom extensions allow you to handle Microsoft Entra authentication events, integrate with external systems, and customize what happens in your application authentication experience. For example, a custom claims provider is a custom extension that allows you to enrich or customize application tokens with information from external systems that can't be stored as part of the Microsoft Entra directory.

Authentication events trigger

The authentication events trigger allows a function to be executed when an authentication event is sent from the Microsoft Entra event service.

Authentication events trigger output binding

The authentication events trigger output binding allows a function to send authentication event actions to the Microsoft Entra event service.

Documentation

  • One the function has been published, there's some good reading about logging and metrics that can be found here

  • For API Documentation, please see the (Link TBD)

  • Once this moves to preview, we except no breaking changes and would be as simple as removing the the NuGet source that points to the private preview.

Examples

To Test Token Augmentation, please do the following.

  • Start Visual Studio.
  • Open the project that was created in the prior step. (QuickStart)
  • Run the Application. (F5)
  • Once the Azure functions developer's application has started, copy the listening url that is displayed with the application starts up.
  • Note: All Authentication functions are listed, in the case we have one function listener registered called "OnTokenIssuanceStart"
  • Your function endpoint will then be a combination of the listening url and function, for example: "http://localhost:7071/runtime/webhooks/AuthenticationEvents?code=(YOUR_CODE)&function=OnTokenIssuanceStart"
  • Post the following payload using something like Postman or Fiddler.
  • Steps for using Postman can be found (Link TBD)
{
  "type":"microsoft.graph.authenticationEvent.TokenIssuanceStart",
  "source":"/tenants/{tenantId}/applications/{resourceAppId}",
  "data":{
    "@odata.type": "microsoft.graph.onTokenIssuanceStartCalloutData",
    "tenantId": "30000000-0000-0000-0000-000000000003",
    "authenticationEventListenerId1": "10000000-0000-0000-0000-000000000001",
    "customAuthenticationExtensionId": "10000000-0000-0000-0000-000000000002",
    "authenticationContext1":{
      "correlationId": "20000000-0000-0000-0000-000000000002",
      "client": {
        "ip": "127.0.0.1",
        "locale": "en-us",
        "market": "en-au"
      },
      "authenticationProtocol": "OAUTH2.0",
      "clientServicePrincipal": {
        "id": "40000000-0000-0000-0000-000000000001",
        "appId": "40000000-0000-0000-0000-000000000002",
        "appDisplayName": "Test client app",
        "displayName": "Test client application"
      },
      "resourceServicePrincipal": {
        "id": "40000000-0000-0000-0000-000000000003",
        "appId": "40000000-0000-0000-0000-000000000004",
        "appDisplayName": "Test resource app",
        "displayName": "Test resource application"
      },
      "user": {
        "companyName": "Nick Gomez",
        "country": "USA",
        "createdDateTime": "0001-01-01T00:00:00Z",
        "displayName": "Dummy display name",
        "givenName": "Example",
        "id": "60000000-0000-0000-0000-000000000006",
        "mail": "test@example.com",
        "onPremisesSamAccountName": "testadmin",
        "onPremisesSecurityIdentifier": "DummySID",
        "onPremisesUserPrincipalName": "Dummy Name",
        "preferredDataLocation": "DummyDataLocation",
        "preferredLanguage": "DummyLanguage",
        "surname": "Test",
        "userPrincipalName": "testadmin@example.com",
        "userType": "UserTypeCloudManaged"
      }
    }
  }
}
  • You should see this response:
{
    "data": {
        "@odata.type": "microsoft.graph.onTokenIssuanceStartResponseData",
        "actions": [
            {
                "@odata.type": "microsoft.graph.provideClaimsForToken",
                "claims": {
                    "DateOfBirth": "01/01/2000",
                    "CustomRoles": [
                            "Writer",
                            "Editor"
                        ]
                    }
             }
        ]
    }
}

Troubleshooting

  • Visual Studio Code
    • If running in Visual Studio Code, you get an error along the lines of the local Azure Storage Emulator is unavailable, you can start the emulator manually.! (Note: Azure Storage emulator is now deprecated and the suggested replacement is Azurite)
    • If using Visual Studio Code on Mac please use Azurite
    • If you see the following error on Windows (it's a bug) when trying to run the created projected.
    • This can be resolved by executing this command in powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine more info on this can be found here and here

Next steps

For more information on Azure SDK, please refer to this website

Publish

  • Follow the instruction here to create and publish your Azure Application. https://learn.microsoft.com/azure/azure-functions/functions-develop-vs?tabs=in-process#publish-to-azure
  • To determine your published posting endpoint, combine the azure function endpoint you created, route to the listener and listener code, the listen code can be found by navigating to your azure function application, selecting "App Keys" and copying the value of AuthenticationEvents_extension.
  • For example: "https://azureautheventstriggerdemo.azurewebsites.net/runtime/webhooks/AuthenticationEvents?code=(AuthenticationEvents_extension_key)&function=OnTokenIssuanceStart"
  • Make sure your production environment has the correct application settings for token authentication.
  • Once again you can test the published function by posting the above payload to the new endpoint.

Contributing

For details on contributing to this repository, see the contributing guide.

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-beta.7 103 4/22/2024
1.0.0-beta.6 222 3/27/2024
1.0.0-beta.5 385 12/8/2023
1.0.0-beta.4 131 11/14/2023
1.0.0-beta.3 501 2/17/2023
1.0.0-beta.2 258 11/8/2022
1.0.0-beta.1 293 9/14/2022