Skip to content

Easily validate OIDC / JWT Bearer Tokens to authenticate users and secure your Azure Functions application

License

Notifications You must be signed in to change notification settings

AspNetMonsters/AzureFunctions.OidcAuthentication

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AzureFunctions.OidcAuthentication

Build status NuGet Badge

This project is originally forked from https://github.com/bryanknox/AzureFunctionsOpenIDConnectAuthSample. Thank you to Bryan for the helpful sample.

Why?

As of writing this, securing Azure Functions using Bearer token is clumsy. For some auth providers, you can enable App Service Authentication in the Azure Portal but that only works for the deployed version of your app which makes testing locally difficult and clumsy.

This library makes it easy to authenticate a user by validating a bearer token.

Requirements

Azure Functions v3 Dependency Injection using Azure Functions Extensions An identity provider (e.g. Auth0, Azure AD, Okta)

How to use it

First, configure dependency injection for your Azure Functions project. Start by adding the Microsoft.Azure.Functions.Exentions NuGet package.

dotnet add package Microsoft.Azure.Functions.Extensions

Add the OidcAuthentication NuGet package to your Azure Functions project.

dotnet package install AzureFunctions.OidcAuthentication

Now add a FunctionStartup class to configure services that will be used in your Azure Functions app. In the Configure method, add a call to builder.Services.AddOidcApiAuthorization(); This will configure the IApiAuthentication service that you will use to authenticate users.

[assembly: FunctionsStartup(typeof(Curbsy.API.Startup.DependencyInjection))]

namespace MySecuredApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddOidcApiAuthorization();
        }
    }
}

Configuration is loaded from a environment variables which can be set in local.settings.json for local development or in the Azure portal for your deployed app. Settings are prefixed with OidcApiAuthSettings:.

Here is an example local.settings.json file for Azure AD B2C:

{
    "IsEncrypted": false,
    "Values": {
      "AzureWebJobsStorage": "UseDevelopmentStorage=true",
      "FUNCTIONS_WORKER_RUNTIME": "dotnet",
      "OidcApiAuthSettings:Audience": "Your API Application's Client ID",
      "OidcApiAuthSettings:MetadataAddress": "https://yourb2cdomain.b2clogin.com/yourb2cdomain.onmicrosoft.com/yoursigninuserflowname/v2.0/.well-known/openid-configuration/",
      "OidcApiAuthSettings:IssuerUrl": "https://yourb2cdomain.b2clogin.com/Your Directory (tenant) ID/v2.0/"
    }
}

Settings

OidcApiAuthSettings:Audience - Required

Identifies the API to be authorized by the Open ID Connect provider (issuer).

The "Audience" is the identifer used by the authorization provider to identify the API (HTTP triggered Azure Function) being protected. This is often a URL but it is not used as a URL is is simply used as an identifier.

For Auth0 use the API's Identifier in the Auth0 Dashboard.

For Azure AD B2C, use your API Application's (client) ID. This is a GUID.

OidcApiAuthSettings:IssuerUrl - Required

The URL of the Open ID Connect provider (issuer) that will perform API authorization.

The "Issuer" is the URL for the authorization provider's end-point. This URL will be used as part of the OpenID Connect protocol to obtain the the signing keys that will be used to validate the JWT Bearer tokens in incoming HTTP request headers.

For Auth0 the URL format is: https://{Auth0-tenant-domain}.auth0.com For Auzre AD B2C, the format is: https://yourb2cdomain.b2clogin.com/Your Directory (tenant) ID/v2.0/

OidcApiAuthSettings:MetadataAddress - Optional (depending on identity provider)

The URL for the identity provider's well-known openid-configuration url.

Default Vaule: $"{IssuerUrl}.well-known/openid-configuration"

For Auth0, leave this blank. For Azure AD B2C, use https://yourb2cdomain.b2clogin.com/yourb2cdomain.onmicrosoft.com/yoursigninuserflowname/v2.0/.well-known/openid-configuration/

OidcApiAuthSettings:NameClaimType - Optional

A string defining the name of the claim that will identify the user's name

Default value: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

OidcApiAuthSettings:RoleClaimType - Optional

A string defining the name of the claim that will identify the user's role membership

Default value: "http://schemas.microsoft.com/ws/2008/06/identity/claims/roleidentifier"

Securing an Azure Function

Not that everything is configured, you can inject the IApiAuthentication service into your Azure Function and authenticate users as follows:

namespace MySecuredApp
{
    public class MyFunction
    {
        private readonly IApiAuthentication apiAuthentication;

        public MyFunction(IApiAuthentication apiAuthentication)
        {
            this.apiAuthentication = apiAuthentication;
        }
        
        [FunctionName("MyFunction")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            // Authenticate the user
            var authResult = await this.apiAuthentication.AuthenticateAsync(req.Headers);

            // Check the authentication result
            if (authResult.Failed)
            {
                return new ForbidResult(authenticationScheme: "Bearer");
            }
            
            // User is authenticated. Proceed with function logic
            string name = authResult.User.Identity.Name; // This gives us the unique user name
            
            string responseMessage = $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
   }
}

AuthResult.User is a ClaimsPrincipal that is created using the claims that were included in the JWT token that was validated by the IApiAuthentication service. You can use authResult.User to inspect the user's claims and add your own authorization rules inside your Function.

End-to-end Sample

About

Easily validate OIDC / JWT Bearer Tokens to authenticate users and secure your Azure Functions application

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages