Skip to content
Jean-Marc Prieur edited this page Feb 27, 2021 · 26 revisions

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:

image

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();

Performance improvement in the cache for AcquireTokenForApp in multi-tenant applications

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

Getting started with Microsoft Identity Web

Token cache serialization

Web apps

Web APIs

Daemon scenario

Advanced topics

FAQ

News

Contribute

Other resources

Clone this wiki locally