Using Key Vault certificates with Microsoft.Identity.Web and ASP.NET Core applications

This post shows how Azure Key Vault certificates can be used with Microsoft.Identity.Web in an ASP.NET Core application which requires a downstream “access_as_user” API. The Azure AD App Registrations requires a certificate instead of a client secret.

Code: https://github.com/damienbod/AzureADAuthRazorUiServiceApiCertificate

Creating the Key Vault certificates

The certificate which will be used in the ASP.NET Core applications can be created in Azure Key Vault. The .cer export needs to be downloaded after the certificate has been created.

The certificate can then be uploaded to the Azure App Registration. Certificates are used for authentication instead of secrets.

The Azure App Registration and the downstream API App Registration is configured as shown in this post.

The delegated API permission with the access_as_user scope is added. Other standard OIDC delegated permissions are added as required.

The Startup class uses Microsoft.Identity.Web to setup the authentication and configure the API access like in the documentation. AddMicrosoftIdentityWebAppAuthentication is used and the EnableTokenAcquisitionToCallDownstreamApi for the user access token.

Note: when using AddInMemoryTokenCaches, there is a problem when running in Visual studio 2019. After every start, you need to delete the cookies manually from the browser, otherwise an exception is thrown. This is because after each restart, the cache gets emptied but the cookie remains. This is a bit of a pain using Microsoft.Identity.Web. At present, this can only be fixed by using a persistant cache.

public void ConfigureServices(IServiceCollection services)
{
	services.AddTransient<ApiService>();
	services.AddHttpClient();

	services.AddOptions();

	string[] initialScopes = Configuration.GetValue<string>(
          "CallApi:ScopeForAccessToken")?.Split(' ');

	services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
		.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
		.AddInMemoryTokenCaches();

	services.AddRazorPages().AddMvcOptions(options =>
	{
		var policy = new AuthorizationPolicyBuilder()
			.RequireAuthenticatedUser()
			.Build();
		options.Filters.Add(new AuthorizeFilter(policy));
	}).AddMicrosoftIdentityUI();
}

Azure Key Vault Certificate Setup

The Azure Key Vault certificates can now be configured in the ASP.NET Core application. The applications need to work in Azure when deployed and also when debugging locally in Visual Studio 2019.

The Certificate configuration is added to the AzureAd app.settings. The ClientCertificates settings using Key Vault is configured to use the same certificate created above which was uploaded to the Azure App Registration for the application.

"AzureAd": {
	"Instance": "https://login.microsoftonline.com/",
	"Domain": "damienbodhotmail.onmicrosoft.com",
	"TenantId": "7ff95b15-dc21-4ba6-bc92-824856578fc1",
	"ClientId": "8e2b45c2-cad0-43c3-8af2-b32b73de30e4",
	"CallbackPath": "/signin-oidc",
	"SignedOutCallbackPath ": "/signout-callback-oidc",
	"ClientCertificates": [
	  {
		"SourceType": "KeyVault",
		"KeyVaultUrl": "https://damienbod.vault.azure.net",
		"KeyVaultCertificateName": "DcPortalCert"
	  }
	],
	"TokenDecryptionCertificates": [
	  {
		"SourceType": "KeyVault",
		"KeyVaultUrl": "https://damienbod.vault.azure.net",
		"KeyVaultCertificateName": "DecryptionCertificateCert"
	  }
	]
},
"CallApi": {
	"ScopeForAccessToken": "api://fdc48df2-2b54-411b-a684-7d9868ce1a95/access_as_user",
	"ApiBaseAddress": "https://localhost:44390"
},

The DefaultAzureCredential from Azure SDK is used to access the Azure Key Vault. In Visual Studio 2019, the Environment variables can be used to setup the access, together with your Visual Studio account. If the Azure SDK is setup incorrectly, local debugging will not work when fetching the access token for the API access.

This can be setup by right clicking your project and adding the AZURE_CLIENT_ID, AZURE_TENANT_ID settings for you project.

This can also be configured directly in the launchSettings.json using the environmentVariables. This can then be added to the profiles as required.

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "https://localhost:44377",
      "sslPort": 44377
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "AZURE_CLIENT_ID": "8e2b45c2-cad0-43c3-8af2-b32b73de30e4",
        "AZURE_TENANT_ID": "7ff95b15-dc21-4ba6-bc92-824856578fc1"
      }
    },
    "PortalDecryptionCertificates": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "AZURE_CLIENT_ID": "8e2b45c2-cad0-43c3-8af2-b32b73de30e4",
        "ASPNETCORE_ENVIRONMENT": "Development",
        "AZURE_TENANT_ID": "7ff95b15-dc21-4ba6-bc92-824856578fc1"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    }
  }
}

Now the Azure AD authentication can be used with Azure App Registrations using certificates and run from both Visual Studio 2019 or local debugging and of course Azure deployments.

Links

Authentication and the Azure SDK

https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#second-case-access-token-request-with-a-certificate

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-credential-flows

https://tools.ietf.org/html/rfc7523

https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication

https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-Assertions

https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow

https://github.com/AzureAD/microsoft-identity-web/wiki/Using-certificates#describing-client-certificates-to-use-by-configuration

API Security with OAuth2 and OpenID Connect in Depth with Kevin Dockx, August 2020

https://www.scottbrady91.com/OAuth/Removing-Shared-Secrets-for-OAuth-Client-Authentication

https://github.com/KevinDockx/ApiSecurityInDepth

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki

2 comments

  1. […] Using Key Vault certificates with Microsoft.Identity.Web and ASP.NET Core applications (Damien Bowden) […]

  2. […] Using Key Vault certificates with Microsoft.Identity.Web and ASP.NET Core applications – Damien Bowden […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: