Migración de aplicaciones cliente confidenciales de ADAL.NET a MSAL.NET

En esta guía práctica, aprenderá a migrar una aplicación cliente confidencial de Azure Active Directory Authentication Library para .NET (ADAL.NET) a Biblioteca de autenticación de Microsoft para .NET (MSAL.NET). Las aplicaciones cliente confidenciales incluyen aplicaciones web, las API web y las aplicaciones daemon que invocan otro servicio en nombre propio. Para más información sobre las aplicaciones confidenciales, consulte Flujos de autenticación y escenarios de aplicaciones. Si la aplicación se basa en ASP.NET Core, consulta Microsoft. Identity.Web.

Para los registros de aplicaciones:

  • No es necesario crear un nuevo registro de aplicaciones. (Mantiene el mismo identificador de cliente).
  • No es necesario cambiar las autenticaciones previas (permisos de API con consentimiento del administrador).

Pasos de migración

  1. Busque el código que usa ADAL.NET en la aplicación.

    El código que usa ADAL en una aplicación cliente confidencial crea instancias de AuthenticationContext y llama a AcquireTokenByAuthorizationCode o a una invalidación de AcquireTokenAsync con los parámetros siguientes:

    • Una cadena resourceId. Esta variable es el URI de identificador de aplicación de la API web a la que quiere llamar.
    • Una instancia de IClientAssertionCertificate o ClientAssertion. Esta instancia proporciona las credenciales de cliente para que la aplicación demuestre la identidad de la aplicación.
  2. Una vez que haya identificado que tiene aplicaciones que usan ADAL.NET, instale el paquete NuGet de MSAL.NET Microsoft.Identity.Client y actualice las referencias de biblioteca del proyecto. Para obtener más información, consulte Instalación de un paquete NuGet. Para usar serializadores de caché de tokens, instale Microsoft. Identity.Web.TokenCache.

  3. Actualice el código según el escenario de cliente confidencial. Algunos pasos son comunes y se aplican en todos los escenarios de cliente confidencial. Otros pasos son únicos para cada escenario.

    Escenarios de cliente confidenciales:

Es posible que haya proporcionado un contenedor alrededor de ADAL.NET para controlar los certificados y el almacenamiento en caché. En esta guía se usa el mismo enfoque para ilustrar el proceso de migración de ADAL.NET a MSAL.NET. Sin embargo, este código solo es para fines de demostración. No copie y pegue estos wrappers ni los integre en su código tal como están.

Migración de aplicaciones de demonio

Los escenarios de daemon usan el flujo de OAuth 2.0 de credenciales del cliente. También se denominan llamadas de servicio a servicio. La aplicación adquiere un token en su propio nombre, no en nombre de un usuario.

Averiguar si el código usa escenarios de demonio

El código ADAL de su aplicación usa escenarios de servicio si contiene una llamada a AuthenticationContext.AcquireTokenAsync con los siguientes parámetros:

  • Un recurso (URI de identificador de aplicación) como primer parámetro
  • IClientAssertionCertificate o ClientAssertion como segundo parámetro

AuthenticationContext.AcquireTokenAsync no tiene un parámetro de tipo UserAssertion. Si lo tiene, entonces la aplicación es una API web y usa el escenario de API web que llama a las API web de nivel inferior.

Actualiza el código de los escenarios del daemon

Los pasos siguientes para actualizar el código se aplican en todos los escenarios de cliente confidencial:

  1. Agregue el espacio de nombres MSAL.NET en el código fuente: using Microsoft.Identity.Client;.
  2. En lugar de crear una instancia de AuthenticationContext, use ConfidentialClientApplicationBuilder.Create para crear una instancia de IConfidentialClientApplication.
  3. En lugar de la resourceId cadena, MSAL.NET usa ámbitos. Dado que las aplicaciones que usan ADAL.NET están autenticadas previamente, siempre puede usar los siguientes ámbitos: new string[] { $"{resourceId}/.default" }.
  4. Reemplace la llamada a AuthenticationContext.AcquireTokenAsync por una llamada a IConfidentialClientApplication.AcquireTokenXXX, donde XXX depende de su escenario.

En este caso, reemplace la llamada a AuthenticationContext.AcquireTokenAsync por una llamada a IConfidentialClientApplication.AcquireTokenClient.

Esta es una comparación del código ADAL.NET y MSAL.NET de escenarios de demonio:

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;
}
}

Aprovecha el almacenamiento en caché de tokens

Si no configura el almacenamiento en caché de tokens, el emisor de tokens le impondrá limitaciones, lo que provocará errores. También se tarda mucho menos en obtener un token de la memoria caché (10-20 ms) de lo que es de ESTS (500-30000 ms).

Si desea implementar una caché de tokens distribuida, consulte Caché de tokens para una aplicación web o api web (aplicación cliente confidencial).

Obtenga más información sobre el escenario de demonio y cómo se implementa con MSAL.NET o Microsoft. Identity.Web en nuevas aplicaciones.

Ventajas de MSAL

Entre las principales ventajas de MSAL.NET para la aplicación se incluyen:

  • Resistencia. MSAL.NET ayuda a que la aplicación sea resistente a través de:

    • Ventajas del Servicio de credenciales en caché (CCS) de Microsoft Entra ID. CCS funciona como una copia de seguridad de Microsoft Entra.
    • Renovación proactiva de tokens si la API a la que llama habilita tokens de larga duración a través de Evaluación continua de acceso.
  • Seguridad Puede adquirir tokens de prueba de posesión (PoP) si la API web a la que desea llamar así lo requiere. Para obtener más información, consulte tokens de prueba de posesión en MSAL.NET

  • Rendimiento y escalabilidad. Si no necesita compartir la memoria caché con ADAL.NET, deshabilite la compatibilidad de caché heredada al crear la aplicación cliente confidencial (.WithLegacyCacheCompatibility(false)) para aumentar significativamente el rendimiento.

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

Solución de problemas

MsalServiceException

La siguiente información de solución de problemas realiza dos suposiciones:

  • El código ADAL.NET estaba funcionando.
  • Ha migrado a MSAL manteniendo el mismo identificador de cliente.

Si recibe una excepción con cualquiera de los siguientes mensajes:

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.

Solucione la excepción mediante estos pasos:

  1. Confirme que usa la versión más reciente de MSAL.NET.
  2. Confirme que el host de la autoridad que estableció al crear la aplicación cliente confidencial y el host de la autoridad que usó con ADAL sean similares. En concreto, ¿es la misma nube (Azure Government, Microsoft Azure operada por 21Vianet o Azure Alemania)?

MsalClientException

En las aplicaciones multiinquilino, especifique una autoridad común al compilar la aplicación para tener como destino un inquilino específico, como el inquilino del usuario al llamar a una API web. Desde MSAL.NET 4.37.0, cuando se especifica .WithAzureRegion al crear la aplicación, ya no se puede especificar la autoridad mediante .WithAuthority en las solicitudes de token. Si lo hace, obtendrá el siguiente error al actualizar desde versiones anteriores de 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."

Para corregir este problema, reemplace .WithAuthority en la expresión AcquireTokenXXX por .WithTenantId. Especifique el inquilino mediante un GUID o un nombre de dominio.

Pasos siguientes

Más información sobre: