1.6.0 - mattchenderson/microsoft-identity-web GitHub Wiki
Microsoft.Identity.Web 1.6.0 released
Simplification of the public API
Several among you raised issues telling us they don't want to re-write the same code several times, which is a fair request. In this release we have worked improving the public API based on this feedback. There are no breaking changes, just simplifications;
EnableTokenAcquisitionToCallDownstreamApi simplified
Until Microsoft.Identity.Web 1.6.0, when you were using the delegates overrides of AddMicrosoftIdentityWebApp
, AddMicrosoftIdentityWebApi
, and EnableTokenAcquisitionToCallDownstreamApi
, you had to re-specify, in EnableTokenAcquisitionToCallDownstreamApi
some ConfidentialClientApplicationOptions
(ClientId
, Instance
, TenantId
), that you had already specified in AddMicrosoftIdentityWebApp
or AddMicrosoftIdentityWebApi
.
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(
options => {
Configuration.Bind("AzureAd", options);
// Set some other options.
})
.EnableTokenAcquisitionToCallDownstreamApi(
options => {
Configuration.Bind("AzureAd", options)
}, initialScopes)
Microsoft.Identity.Web 1.6.0 fixes this, and you only need to provide the very options which would not be already in MicrosoftIdentityOptions
.
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(
options =>
{
Configuration.Bind("AzureAd", options);
// Set some other options.
})
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes);
You can still provide a delegate, of course, but it's no longer mandatory if you don't need to setup things that are already setup in AddMicrosoftIdentityWebApp
.
Validating scopes in web APIs, Azure functions and gRPC services is now easier
Until now, you had, in each controller or page action to verify the scopes accepted by a web API, even if this scopes were the same for all the actions of a controller for example
[Authorize]
public class HomeController : Controller
{
static string[] scopeRequiredByAPI = new string[] { "access_as_user" };
...
public async Task<IActionResult> Action1()
{
HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByAPI);
// do something
}
public async Task<IActionResult> Action2()
{
HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByAPI);
// do something
}
}
From Microsoft.Identity.Web 1.6.0, you can achieve the same result by adding the RequiredScope
attribute, which takes directly the scopes to validate, or a key to the configuration settings where to look for these scopes. We also added an Obsolete warning if you call VerifyUserHasAnyAcceptedScope
with an aka.ms link to help you migrate.
[Authorize]
[RequiredScope("access_as_user")
public class HomeController : Controller
{
/// ...
public async Task<IActionResult> Action()
{
}
}
For a full discussion of all the possibilities of this attribute, see: https://aka.ms/ms-id-web/required-scope-attribute
It's easier to rotate decrypt certificates in web APIs, Azure functions, gRPC services
When a web API/Azure function/gRPC service requires token encryption, you were on your own to rotate the certificates. It's now possible to specific several TokenDecryption certificate descriptions in the configuration, and Microsoft.Identity.Web will do the right thing to use the right one.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
// ...
"TokenDecryptionCertificates": [
{
"SourceType": "",
"Container": "",
"ReferenceOrValue": ""
},
{
"SourceType": "",
"Container": "",
"ReferenceOrValue": ""
}
]
},
Read more about token decryption.
Support for Azure functions and gRPC services protected by the Microsoft identity platform
Microsoft.Identity.Web now supports (in addition to web apps, web APIs, and blazor apps), Azure functions and gRPC services, protected by the MIcrosoft.Identity.Platform. These behave like web APIs, and therefore, protected with AAD, can call Microsoft Graph or downstream APIs.
Microsoft.Identity.Web.ProjectTemplates.1.6.0 and above also contains project templates to create these Azure functions and web APIs. See:
- Using the worker2 project template for details on how to create a new gPRC application
Certificate loaders for ASP.NET, or .NET Framework applications (including from KeyVault)
In the continuation of version 1.4.0 where Microsoft.Identity.Web provided token cache serialization for ASP.NET framework and .NET framework, version 1.6.0 now adds support for certificate description and loading, to be used with MSAL.NET.
Two samples were updated to show how to do:
Details about the documentation are available from: Support for ASP.NET classic and more generally .NET 4.7.2
For instance:
The certificate is described in the appsettings.json of the daemon application
{
"Instance": "https://login.microsoftonline.com/{0}",
"ApiUrl": "https://graph.microsoft.com/",
"Tenant": "msidentitysamplestesting.onmicrosoft.com",
"ClientId": "6af093f3-b445-4b7a-beae-046864468ad6",
"Certificate":
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
"KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
}
}
and it's loaded using Microsoft.Identity.Web,'s DefaultCertificateLoader (from Microsoft.Identity.Web 1.6.0)
// Load the certificate
ICertificateLoader certificateLoader = new DefaultCertificateLoader();
certificateLoader.LoadIfNeeded(config.Certificate);
// Even if this is a console application here, a daemon application is a confidential client application
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithCertificate(config.Certificate.Certificate)
.WithAuthority(new Uri(config.Authority))
.Build();
AcquireTokenForApp
in multi-tenant applications
Performance improvement in the cache for We got the feedback that multi-tenant applications using ITokenAcquisition.GetTokenForAppAsync
could end-up having a lot of tokens in the App token cache if they were manipulating many tenant. Microsoft.Identity.Web 1.6.0 leverages MSAL.NET 4.26.0 which changed the way the cache suggested cache key is computed when calling AcquireTokenForClient
(which is itself called by ITokenAcquisition.GetTokenForAppAsync
). This is in order to provide a better peformance. Before Microsoft.Identity.Web 1.6.0, the cache key was $"{ClientId}AppTokenCache", whereas from Microsoft.Identity.Web 1.6.0 it becomes $"{ClientId}{tenantID]_AppTokenCache".
In practice this means that when you update your multi-tenant applications, it will re-obtain once tokens for the downtream service for each tenant, but then you should see considerably better performance