-
Notifications
You must be signed in to change notification settings - Fork 218
Using certificates
Microsoft.Identity.Web uses certificates in two situations:
- In web apps and web APIs, to prove the identity of the application, instead of using a client secret.
- In web APIs, to decrypt tokens if the web API opted to get encrypted tokens.
This article explains both usages, as well as describes the certificates to use.
Table of contents:
-
Using certificates with Microsoft.Identity.Web
- Client certificates
- Decryption certificates
-
Specifying certificates
- Getting certificates from Key Vault
- Specifying certificates from a path
- Specifying certificates from a certificate store by distinguished name
- Specifying certificates from a certificate store by thumbprint
- Specifying certificates from a certificate store by Base64 encoded value
- Specifying certificates as an X509Certificate2
- Microsoft Identity Web classes used for certificate management
Web apps and web APIs are confidential client applications.
They can prove their identity to Azure AD or Azure AD B2C by 3 means:
Method | Supported in Microsoft.Identity.Web |
---|---|
Client secrets | Yes |
Client certificates | Yes |
Client assertions | Not yet |
Microsoft.Identity.Web supports specifying client certificates. The configuration property to specify the client certificates is ClientCertificates. It is an array of certificate descriptions. There are several ways of describing certificates. see Specifying certificates below.
You can express the client certificates in the ClientCertificates property. ClientCertificates and ClientSecret are mutually exclusive.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "msidentitysamplestesting.onmicrosoft.com",
"TenantId": "7f58f645-c190-4ce5-9de4-e2b7acd2a6ab",
"ClientId": "86699d80-dd21-476a-bcd1-7c1a3d471f75",
"ClientCertificates": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
]
}
}
See Specifying certificates below for all the ways to describe certificates.
You can also specify the certificate description programmatically. For this you add CertificateDescription
instances to the ClientCertificates
property of MicrosoftIdentityOptions
. You can then use some of the overloads of AddMicrosoftIdentityWebApp
, EnableTokenAcquisitionToCallDownstreamApi
using delegates to set the MicrosoftIdentityOptions
.
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.ClientCertificates = new CertificateDescription[] {
CertificateDescription.FromKeyVault("https://msidentitywebsamples.vault.azure.net",
"MicrosoftIdentitySamplesCert")
};
See Specifying certificates below for all the ways to describe certificates.
Web APIs can request token encryption (for privacy reasons). This is even compulsory for first-party (Microsoft) web APIs that access MSA identities. The configuration property to specify the client certificates is TokenDecryptionCertificates. It is an array of descriptions of certificates.
You can express the decryption certificates in the TokenDecryptionCertificates
property.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "msidentitysamplestesting.onmicrosoft.com",
"TenantId": "7f58f645-c190-4ce5-9de4-e2b7acd2a6ab",
"ClientId": "86699d80-dd21-476a-bcd1-7c1a3d471f75",
"TokenDecryptionCertificates": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
]
}
}
See Specifying certificates below for all the ways to describe certificates.
You can also specify the certificate description programmatically:
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.TokenDecryptionCertificates = new CertificateDescription[] {
CertificateDescription.FromKeyVault("https://msidentitywebsamples.vault.azure.net",
"MicrosoftIdentitySamplesCert")
};
See Specifying certificates below for all the ways to describe certificates.
It's possible to specify if the x5c claim (public key of the certificate) should be sent to the STS each time the web app or web API calls Azure AD. Sending the x5c enables application developers to achieve easy certificate rollover in Azure AD: this method will send the public certificate to Azure AD along with the token request, so that Azure AD can use it to validate the subject name based on a trusted issuer policy. This saves the application admin from the need to explicitly manage the certificate rollover (either via portal or PowerShell/CLI operation). For details see https://aka.ms/msal-net-sni.
To specify to send the x5c claim, set the boolean SendX5C
property of the options to true either by configuration
or programmatically.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "msidentitysamplestesting.onmicrosoft.com",
"TenantId": "7f58f645-c190-4ce5-9de4-e2b7acd2a6ab",
"ClientId": "86699d80-dd21-476a-bcd1-7c1a3d471f75",
"TokenDecryptionCertificates": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
],
"SendX5C": "true"
}
}
You can describe the certificates to load, either by configuration, or programmatically:
- from the certificate store (Windows) and a thumbprint ("440A5BE6C4BE2FF02A0ADBED1AAA43D6CF12E269"),
- from the certificate store (Windows) and a distinguished name ("CN=TestCert"),
- from a path on the disk and optionally a password (probably only for debugging locally),
- directly from a Base64 representation of the certificate,
- from Azure Key Vault,
- directly providing it (programmatically only).
Describing the certificate by configuration allows for just-in-time loading, rather than paying the startup cost. For instance for a web app that signs in a user, do not load the certificate until an access token is needed to call a web API.
When your certificate is in Key Vault, Microsoft.Identity.Web leverages Managed Identity, therefore enabling your application to have the same code when deployed (for instance on a VM or Azure app services), or locally on your developer box (using developer credentials).
The following sections show how to specify the client credential certificates, but the principle is the same for the decryption certificates. Just replace ClientCertificates
with TokenDecryptionCertificates
.
To fetch certificates from KeyVault, Microsoft.Identity.Web leverages Managed Identity through the Azure SDK DefaultAzureCredential.
This works out of the box on the developer machine using the developer credentials, and also when deployed with Service fabric or App Services in Azure provided you've been using a System-assigned Managed identity.
However:
-
If you are using a User-assigned managed identity, you will need to set an environment variable AZURE_CLIENT_ID to be the user-assigned managed identity clientID. You can do that through the Azure portal:
- Go to Azure App Service -> Settings | Configuration -> Application Settings
- Add or update the
AZURE_CLIENT_ID
app setting to the user assigned managed identity ID.
-
When used on your developer machine, you have several accounts in Visual Studio, you'll need to specify which account to use, by setting another environement variable
AZURE_USERNAME
{
"ClientCertificates": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
]
}
}
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.ClientCertificates = new CertificateDescription[] {
CertificateDescription.FromKeyVault("https://msidentitywebsamples.vault.azure.net",
"MicrosoftIdentitySamplesCert")
};
{
"ClientCertificates": [
{
"SourceType": "Path",
"CertificateDiskPath": "c:\\temp\\WebAppCallingWebApiCert.pfx",
"CertificatePassword": "password"
}]
}
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.ClientCertificates = new CertificateDescription[] {
CertificateDescription.FromPath(@"c:\temp\WebAppCallingWebApiCert.pfx",
"password")
};
{
"ClientCertificates": [
{
"SourceType": "StoreWithDistinguishedName",
"CertificateStorePath": "CurrentUser/My",
"CertificateDistinguishedName": "CN=WebAppCallingWebApiCert"
}]
}
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.ClientCertificates = new CertificateDescription[] {
CertificateDescription.FromStoreWithDistinguishedName(StoreLocation.CurrentUser,
StoreName.My,
"CN=WebAppCallingWebApiCert")
};
{
"ClientCertificates": [
{
"SourceType": "StoreWithThumbprint",
"CertificateStorePath": "CurrentUser/My",
"CertificateThumbprint": "962D129A859174EE8B5596985BD18EFEB6961684"
}]
}
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.ClientCertificates = new CertificateDescription[] {
CertificateDescription.FromStoreWithThumbprint(StoreLocation.CurrentUser,
StoreName.My,
"962D129A859174EE8B5596985BD18EFEB6961684")
};
{
"ClientCertificates": [
{
"SourceType": "Base64Encoded",
"Base64EncodedValue": "MIIDHzCCAgegA.....r1n8Czew8TPfab4OG37BuEMNmBpqoRrRgFnDzVtItOnhuFTa0="
}]
}
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.ClientCertificates = new CertificateDescription[] {
CertificateDescription.FromBase64Encoded("MIIDHzCCAgegA.....r1n8Czew8TPfab4OG37BuEMNmBpqoRrRgFnDzVtItOnhuFTa0=")
};
You can also directly specify the certificate description as an X509Certificate2 that would you have loaded. This is only possible programmatically
MicrosoftIdentityOptions options = new MicrosoftIdentityOptions();
options.ClientCertificates = new CertificateDescription[] {
CertificateDescription.FromCertificate(x509certificate2)
};
This is a class diagram showing how the classes involved in certificate management in Microsoft.Identity.Web are articulated:
- Home
- Why use Microsoft Identity Web?
- Web apps
- Web APIs
- Using certificates
- Minimal support for .NET FW Classic
- Logging
- Azure AD B2C limitations
- Samples
- Web apps
- Web app samples
- Web app template
- Call an API from a web app
- Managing incremental consent and conditional access
- Web app troubleshooting
- Deploy to App Services Linux containers or with proxies
- SameSite cookies
- Hybrid SPA
- Web APIs
- Web API samples
- Web API template
- Call an API from a web API
- Token Decryption
- Web API troubleshooting
- web API protected by ACLs instead of app roles
- gRPC apps
- Azure Functions
- Long running processes in web APIs
- Authorization policies
- Generic API
- Customization
- Logging
- Calling graph with specific scopes/tenant
- Multiple Authentication Schemes
- Utility classes
- Setting FIC+MSI
- Mixing web app and web API
- Deploying to Azure App Services
- Azure AD B2C issuer claim support
- Performance
- specify Microsoft Graph scopes and app-permissions
- Integrate with Azure App Services authentication
- Ajax calls and incremental consent and conditional access
- Back channel proxys
- Client capabilities