Eseguire la migrazione di applicazioni client riservate da ADAL.NET a MSAL.NET

In questa guida pratica si eseguirà la migrazione di un'applicazione client riservata da Azure Active Directory Authentication Library per .NET (ADAL.NET) a Libreria di Autenticazione Microsoft per .NET (MSAL.NET). Le applicazioni client riservate includono app Web, API Web e applicazioni daemon che chiamano un altro servizio per proprio conto. Per altre informazioni sulle app riservate, vedere Flussi di autenticazione e scenari di applicazione. Se l'app è basata su ASP.NET Core, vedi Microsoft. Identity.Web.

Per le registrazioni dell'app:

  • Non è necessario creare una nuova registrazione dell'app. (Mantieni lo stesso ID cliente.)
  • Non è necessario modificare le preautenzioni (autorizzazioni API con consenso amministratore).

Passaggi per la migrazione

  1. Trovare il codice che usa ADAL.NET nell'app.

    Il codice che usa ADAL in un'app client riservata crea un'istanza AuthenticationContext e chiama AcquireTokenByAuthorizationCode o una sostituzione di AcquireTokenAsync con i parametri seguenti:

    • Una stringa resourceId. Questa variabile è l'URI ID app dell'API Web che si vuole chiamare.
    • Istanza di IClientAssertionCertificate o ClientAssertion. Questa istanza fornisce le credenziali client per l'app per dimostrare l'identità dell'app.
  2. Dopo aver identificato che sono presenti app che usano ADAL.NET, installare il pacchetto NuGet MSAL.NET Microsoft. Identity.Client e aggiornare i riferimenti alla libreria di progetti. Per altre informazioni, vedere Installare un pacchetto NuGet. Per usare i serializzatori di cache dei token, installare Microsoft. Identity.Web.TokenCache.

  3. Aggiornare il codice in base allo scenario client riservato. Alcuni passaggi sono comuni e si applicano a tutti gli scenari client riservati. Altri passaggi sono univoci per ogni scenario.

    Scenari client riservati:

È possibile che sia stato fornito un wrapper intorno ad ADAL.NET per gestire i certificati e la memorizzazione nella cache. Questa guida usa lo stesso approccio per illustrare il processo di migrazione da ADAL.NET a MSAL.NET. Tuttavia, questo codice è solo a scopo dimostrativo. Non copiare/incollare questi wrapper o integrarli nel codice così com'è.

Eseguire la migrazione di app daemon

Gli scenari daemon usano il flusso di credenziali client OAuth2.0. Sono anche dette chiamate tra servizi. L'app acquisisce un token per proprio conto, non per conto di un utente.

Scoprire se il codice usa scenari daemon

Il codice ADAL per l'app usa scenari daemon se contiene una chiamata a AuthenticationContext.AcquireTokenAsync con i parametri seguenti:

  • Una risorsa (URI ID app) come primo parametro
  • IClientAssertionCertificate o ClientAssertion come secondo parametro

AuthenticationContext.AcquireTokenAsync non ha un parametro di tipo UserAssertion. Se sì, la tua app è un'API web e usa lo scenario API web che chiama API web downstream.

Aggiornare il codice degli scenari daemon

I passaggi seguenti per l'aggiornamento del codice si applicano a tutti gli scenari client riservati:

  1. Aggiungi lo spazio dei nomi MSAL.NET nel codice sorgente: using Microsoft.Identity.Client;.
  2. Anziché istanziare AuthenticationContext, usare ConfidentialClientApplicationBuilder.Create per istanziare IConfidentialClientApplication.
  3. Anziché la stringa resourceId, MSAL.NET usa gli scope. Poiché le applicazioni che usano ADAL.NET sono pre-autorizzate, è sempre possibile usare gli ambiti seguenti: new string[] { $"{resourceId}/.default" }.
  4. Sostituisci la chiamata a AuthenticationContext.AcquireTokenAsync con una chiamata a IConfidentialClientApplication.AcquireTokenXXX, dove XXX dipende dal tuo scenario.

In questo caso, sostituire la chiamata a AuthenticationContext.AcquireTokenAsync con una chiamata a IConfidentialClientApplication.AcquireTokenClient.

Di seguito è riportato un confronto tra codice ADAL.NET e MSAL.NET per gli scenari daemon:

ADAL

MSAL

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

public partial class AuthWrapper
{
const string ClientId = "Guid (AppID)";
const string authority 
= "https://login.microsoftonline.com/{tenant}";
// App ID URI of web API to call
const string resourceId = "https://target-api.domain.com";
X509Certificate2 certificate = LoadCertificate();



public async Task<AuthenticationResult> GetAuthenticationResult()
{


var authContext = new AuthenticationContext(authority);
var clientAssertionCert = new ClientAssertionCertificate(
ClientId,
certificate);


var authResult = await authContext.AcquireTokenAsync(
resourceId,
clientAssertionCert,
);

return authResult;
}
}
using Microsoft.Identity.Client;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

public partial class AuthWrapper
{
const string ClientId = "Guid (Application ID)";
const string authority 
= "https://login.microsoftonline.com/{tenant}";
// App ID URI of web API to call
const string resourceId = "https://target-api.domain.com";
X509Certificate2 certificate = LoadCertificate();

IConfidentialClientApplication app;

public async Task<AuthenticationResult> GetAuthenticationResult()
{

var app = ConfidentialClientApplicationBuilder.Create(ClientId)
.WithCertificate(certificate)
.WithAuthority(authority)
.Build();

// Setup token caching https://learn.microsoft.com/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=aspnet
// For example, for an in-memory cache with 1GB limit, use  
app.AddInMemoryTokenCache(services =>
{
// Configure the memory cache options
services.Configure<MemoryCacheOptions>(options =>
{
options.SizeLimit = 1024 * 1024 * 1024; // in bytes (1 GB of memory)
});
}

var authResult = await app.AcquireTokenForClient(
new [] { $"{resourceId}/.default" })
// .WithTenantId(specificTenant)
// See https://aka.ms/msal.net/withTenantId
.ExecuteAsync()
.ConfigureAwait(false);

return authResult;
}
}

Trarre vantaggio dalla memorizzazione nella cache dei token

Se non si configura la memorizzazione nella cache dei token, l'autorità emittente del token limita l'utente, generando errori. Richiede anche molto meno per ottenere un token dalla cache (10-20 ms) rispetto a ESTS (500-30000 ms).

Per implementare una cache di token distribuita, vedere Cache dei token per un'app Web o un'API Web (applicazione client riservata).

Altre informazioni sullo scenario del daemon e su come viene implementato con MSAL.NET o Microsoft. Identity.Web nelle nuove applicazioni.

Vantaggi di MSAL

I vantaggi principali delle MSAL.NET per l'app includono:

  • Resilienza. MSAL.NET consente di rendere resiliente l'app tramite:

    • Vantaggi del servizio Credenziali memorizzate nella cache (CCS) di Microsoft Entra ID. CCS funziona come backup di Microsoft Entra.
    • Rinnovo proattivo dei token se l'API chiamata abilita i token di lunga durata tramite la valutazione continua dell'accesso.
  • Security. È possibile acquisire token di verifica del possesso (PoP) se l'API Web che si vuole chiamare lo richiede. Per informazioni dettagliate, vedere Token di prova del possesso in MSAL.NET

  • Prestazioni e scalabilità. Se non è necessario condividere la cache con ADAL.NET, disabilitare la compatibilità della cache legacy quando si crea l'applicazione client riservata (.WithLegacyCacheCompatibility(false)) per migliorare significativamente le prestazioni.

    app = ConfidentialClientApplicationBuilder.Create(ClientId)
            .WithCertificate(certificate)
            .WithAuthority(authority)
            .WithLegacyCacheCompatibility(false)
            .Build();
    

Troubleshooting

MsalServiceException

Le seguenti informazioni sulla risoluzione dei problemi fanno due presupposti:

  • Il codice ADAL.NET funzionava.
  • È stata eseguita la migrazione a MSAL mantenendo lo stesso ID client.

Se viene visualizzata un'eccezione con uno dei messaggi seguenti:

AADSTS700027: Client assertion contains an invalid signature. [Reason - The key was not found.]

AADSTS90002: Tenant 'aaaabbbb-0000-cccc-1111-dddd2222eeee' not found. This may happen if there are no active subscriptions for the tenant. Check to make sure you have the correct tenant ID. Check with your subscription administrator.

Risolvere i problemi relativi all'eccezione attenendosi alla procedura seguente:

  1. Verificare di usare la versione più recente di MSAL.NET.
  2. Verifica che l'host dell'autorità impostato quando hai creato l'app client confidenziale e l'host dell'autorità utilizzato con ADAL siano simili. In particolare, è lo stesso cloud (Azure per enti pubblici, Microsoft Azure gestito da 21Vianet o Azure Germania)?

MsalClientException

Nelle app multi-tenant specificare un'autorità comune quando si compila l'app per specificare un tenant specifico, ad esempio il tenant dell'utente quando si chiama un'API Web. Poiché MSAL.NET 4.37.0, quando si specifica .WithAzureRegion al momento della creazione dell'app, non è più possibile specificare l'autorità usando .WithAuthority durante le richieste di token. In questo caso, si riceverà l'errore seguente durante l'aggiornamento dalle versioni precedenti di MSAL.NET:

MsalClientException - "You configured WithAuthority at the request level, and also WithAzureRegion. This is not supported when the environment changes from application to request. Use WithTenantId at the request level instead."

Per risolvere questo problema, sostituire .WithAuthority nell'espressione AcquireTokenXXX da .WithTenantId. Specificare il tenant usando un GUID o un nome di dominio.

Passaggi successivi

Altre informazioni su: