Configure el inicio de sesión en Microsoft. Identity.Web

Microsoft. Identity.Web se integra con la infraestructura de registro de ASP.NET Core. Úselo para diagnosticar problemas en:

  • Flujos de autenticación : inicio de sesión, cierre de sesión, validación de tokens
  • Adquisición de tokens: aciertos o errores de caché de tokens, operaciones de MSAL
  • Llamadas API de bajada : solicitudes HTTP, adquisición de tokens para las API
  • Condiciones de error : excepciones, errores de validación

Descripción de los componentes registrados

Componente Origen del registro propósito
Microsoft. Identity.Web Lógica de autenticación principal Configuración, adquisición de tokens, llamadas API
MSAL.NET Microsoft.Identity.Client Operaciones de caché de tokens, validación de autoridad
IdentityModel Validación de tokens Análisis de JWT, validación de firmas, extracción de notificaciones
ASP.NET Core Auth Microsoft.AspNetCore.Authentication Operaciones de cookies, desafíos o acciones prohibidas

Introducción al registro de eventos

Configuración mínima

Agregue las siguientes entradas de nivel de registro a appsettings.json para habilitar el registro de identidades:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Identity": "Information"
    }
  }
}

Esto habilita el registro a nivel de información para Microsoft.Identity.Web y sus dependencias (MSAL.NET, IdentityModel).

Configuración de desarrollo

Para obtener diagnósticos detallados durante el desarrollo:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Identity": "Debug",
      "Microsoft.AspNetCore.Authentication": "Information"
    }
  },
  "AzureAd": {
    "EnablePiiLogging": true  // Development only!
  }
}

Configuración de producción

En el caso de producción, minimice el volumen de registro al capturar errores:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft": "Warning",
      "Microsoft.Identity": "Warning"
    }
  },
  "AzureAd": {
    "EnablePiiLogging": false  // Never true in production
  }
}

Configuración del filtrado de registros

Filtrado basado en espacios de nombres

Controlar la verbosidad del registro por espacio de nombres. La configuración siguiente establece niveles granulares para cada espacio de nombres relacionado con la identidad:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",

      // General Microsoft namespaces
      "Microsoft": "Warning",
      "Microsoft.AspNetCore": "Warning",

      // Identity-specific namespaces
      "Microsoft.Identity": "Information",
      "Microsoft.Identity.Web": "Information",
      "Microsoft.Identity.Client": "Information",

      // ASP.NET Core authentication
      "Microsoft.AspNetCore.Authentication": "Information",
      "Microsoft.AspNetCore.Authentication.JwtBearer": "Information",
      "Microsoft.AspNetCore.Authentication.OpenIdConnect": "Debug",

      // Token validation
      "Microsoft.IdentityModel": "Warning"
    }
  }
}

Deshabilitación del registro específico

Para silenciar los componentes ruidosos sin afectar a otros, establezca su nivel de registro a None o Warning.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Identity.Web": "None",  // Completely disable
      "Microsoft.Identity.Client": "Warning"  // Only errors/warnings
    }
  }
}

Configuración específica del entorno

Use appsettings.{Environment}.json para la configuración por entorno:

appsettings.Development.json:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity": "Debug"
    }
  },
  "AzureAd": {
    "EnablePiiLogging": true
  }
}

appsettings.Production.json:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity": "Warning"
    }
  },
  "AzureAd": {
    "EnablePiiLogging": false
  }
}

Comprender los niveles de registro

ASP.NET Core define los siguientes niveles de registro. Elija el nivel que equilibra los detalles de diagnóstico con respecto al volumen de registro de su entorno.

niveles de registro de ASP.NET Core

Level Uso Volumen ¿Producción?
Seguimiento La más detallada, cada operación Muy alto No
Depurar Flujo detallado, útil para desarrollo Alto No
Información Flujo general, eventos clave Moderado Selectivo
Advertencia Condiciones inesperadas pero controladas Low
Error Errores y excepciones Muy bajo
Crítico Errores irrecuperables Muy bajo
None Deshabilitar el registro Ninguno Selectivo

Mapeo de MSAL.NET a niveles de ASP.NET Core

Nivel de MSAL.NET equivalente de ASP.NET Core Descripción
Verbose Debug o Trace Mensajes más detallados
Info Information Eventos de autenticación clave
Warning Warning Condiciones anómalas pero controladas
Error Error o Critical Errores y excepciones

Use las siguientes configuraciones por entorno.

Desarrollo:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity": "Debug",
      "Microsoft.Identity.Client": "Information"
    }
  }
}

Preparación:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity": "Information",
      "Microsoft.Identity.Client": "Warning"
    }
  }
}

Producción:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity": "Warning",
      "Microsoft.Identity.Client": "Error"
    }
  }
}

Configuración del registro de PII

De forma predeterminada, Microsoft. Identity.Web redacta la información de identificación personal (PII) de los registros. Habilite el registro de PII solo en entornos de desarrollo para ver los detalles completos del usuario.

¿Qué es PII?

La información de identificación personal (PII) incluye:

  • Nombres de usuario, direcciones de correo electrónico
  • Nombres para mostrar
  • Identificadores de objeto, identificadores de inquilino
  • Direcciones IP
  • Valores de token, reclamaciones

Advertencia de seguridad

ADVERTENCIA: Usted y su aplicación son responsables de cumplir todos los requisitos normativos aplicables, incluidos los establecidos por el RGPD. Antes de habilitar el registro de PII, asegúrese de que puede controlar de forma segura estos datos potencialmente confidenciales.

Habilitar registro de PII (solo para desarrollo)

Configure EnablePiiLogging a true en el archivo de configuración de desarrollo:

appsettings.Development.json:

{
  "AzureAd": {
    "EnablePiiLogging": true  //  Development/Testing ONLY
  },
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity": "Debug"
    }
  }
}

Controlar el registro de información personal identificable programáticamente

Alternar el registro de Información de Identificación Personal (PII) según el entorno de alojamiento:

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<MicrosoftIdentityOptions>(options =>
{
    // Only enable PII in Development
    options.EnablePiiLogging = builder.Environment.IsDevelopment();
});

¿Qué cambios se han realizado con PII habilitado?

Sin registro de PII:

[Information] Token validation succeeded for user '{hidden}'
[Information] Acquired token from cache for scopes '{hidden}'

Con PII activado:

[Information] Token validation succeeded for user 'john.doe@contoso.com'
[Information] Acquired token from cache for scopes 'user.read api://my-api/.default'

Redacción de PII en los registros

Cuando el registro de PII está deshabilitado, los datos confidenciales se reemplazan por:

  • {hidden} - Oculta los identificadores de usuario.
  • {hash:XXXX} : muestra el hash en lugar del valor real.
  • *** - Oculta los tokens

Uso de identificadores de correlación

Los identificadores de correlación rastrean las solicitudes de autenticación entre servicios. Incluyéndolas en bitácoras y tickets de soporte para acelerar la resolución de los problemas.

¿Qué son los identificadores de correlación?

Un identificador de correlación es un GUID que identifica de forma única una solicitud de autenticación o adquisición de tokens en:

  • Su aplicación
  • plataforma de identidad de Microsoft
  • biblioteca de MSAL.NET
  • servicios back-end de Microsoft

Obtención de identificadores de correlación

Método 1: Desde el resultado de autenticación

Extraiga el identificador de correlación de AuthenticationResult después de una adquisición exitosa de tokens:

using Microsoft.Identity.Web;

public class TodoController : ControllerBase
{
    private readonly ITokenAcquisition _tokenAcquisition;
    private readonly ILogger<TodoController> _logger;

    public TodoController(
        ITokenAcquisition tokenAcquisition,
        ILogger<TodoController> logger)
    {
        _tokenAcquisition = tokenAcquisition;
        _logger = logger;
    }

    [HttpGet]
    public async Task<IActionResult> GetTodos()
    {
        var result = await _tokenAcquisition.GetAuthenticationResultForUserAsync(
            new[] { "user.read" });

        _logger.LogInformation(
            "Token acquired. CorrelationId: {CorrelationId}, Source: {TokenSource}",
            result.CorrelationId,
            result.AuthenticationResultMetadata.TokenSource);

        return Ok(result.CorrelationId);
    }
}

Método 2: A partir de MsalServiceException

Capture el identificador de correlación de MsalServiceException cuando se produce un error en la adquisición de tokens.

using Microsoft.Identity.Client;

try
{
    var token = await _tokenAcquisition.GetAccessTokenForUserAsync(
        new[] { "user.read" });
}
catch (MsalServiceException ex)
{
    _logger.LogError(ex,
        "Token acquisition failed. CorrelationId: {CorrelationId}, ErrorCode: {ErrorCode}",
        ex.CorrelationId,
        ex.ErrorCode);

    // Return correlation ID to user for support
    return StatusCode(500, new {
        error = "authentication_failed",
        correlationId = ex.CorrelationId
    });
}

Método 3: Establecimiento de un identificador de correlación personalizado

Asigne un identificador de correlación personalizado para vincular seguimientos de aplicación con solicitudes de Microsoft Entra ID:

[HttpGet("{id}")]
public async Task<IActionResult> GetTodo(int id)
{
    // Use request trace ID as correlation ID
    var correlationId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

    var todo = await _downstreamApi.GetForUserAsync<Todo>(
        "TodoListService",
        options =>
        {
            options.RelativePath = $"api/todolist/{id}";
            options.TokenAcquisitionOptions = new TokenAcquisitionOptions
            {
                CorrelationId = Guid.Parse(correlationId)
            };
        });

    _logger.LogInformation(
        "Called downstream API. TraceId: {TraceId}, CorrelationId: {CorrelationId}",
        HttpContext.TraceIdentifier,
        correlationId);

    return Ok(todo);
}

Proporcione identificadores de correlación para soporte

Al ponerse en contacto con Microsoft soporte técnico, proporcione los detalles siguientes:

  1. ID de correlación - en registros o excepciones
  2. Marca de tiempo - cuando se produjo el error (UTC)
  3. Tenant ID : el inquilino de Microsoft Entra ID
  4. Código de error : si procede (por ejemplo, AADSTS50058)

Ejemplo de solicitud de soporte técnico:

Subject: Token acquisition failing for user.read scope

Correlation ID: 12345678-1234-1234-1234-123456789012
Timestamp: 2025-01-15 14:32:45 UTC
Tenant ID: contoso.onmicrosoft.com
Error Code: AADSTS50058

Habilitación del registro de caché de tokens

El registro de caché de tokens le ayuda a comprender el comportamiento de aciertos o errores de caché y a diagnosticar problemas de rendimiento con cachés distribuidas.

Habilitación del diagnóstico de caché de tokens

Para aplicaciones .NET Framework o .NET Core que utilizan cachés de tokens distribuidos, configure el registro detallado:

using Microsoft.Extensions.Logging;
using Microsoft.Identity.Web.TokenCacheProviders;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDistributedTokenCaches();

// Enable detailed token cache logging
builder.Services.AddLogging(configure =>
{
    configure.AddConsole();
    configure.AddDebug();
})
.Configure<LoggerFilterOptions>(options =>
{
    options.MinLevel = LogLevel.Debug;  // Detailed cache operations
});

Ejemplos de registro de caché de tokens

Aciertos de caché:

[Debug] Token cache: Token found in cache for scopes 'user.read'
[Information] Token source: Cache

Error de caché:

[Debug] Token cache: No token found in cache for scopes 'user.read'
[Information] Token source: IdentityProvider
[Debug] Token cache: Token stored in cache

Solución de problemas de cachés distribuidas

Habilite el registro específico del proveedor para diagnosticar problemas de rendimiento y conectividad de caché.

Redis Cache:

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration["Redis:ConnectionString"];
});

// Enable Redis logging
builder.Services.AddLogging(configure =>
{
    configure.AddFilter("Microsoft.Extensions.Caching", LogLevel.Debug);
});

SQL Server cache:

Configurar el caché distribuida de SQL Server con el registro de eventos.

builder.Services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = builder.Configuration["SqlCache:ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TokenCache";
});

// Enable SQL cache logging
builder.Services.AddLogging(configure =>
{
    configure.AddFilter("Microsoft.Extensions.Caching.SqlServer", LogLevel.Information);
});

Solucionar problemas comunes

Use los siguientes escenarios para diagnosticar problemas frecuentes de autenticación y autorización.

Escenarios comunes de registro

Escenario 1: Errores de validación de tokens

Síntoma: 401 Respuestas no autorizadas

Habilite el registro detallado:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.Authentication.JwtBearer": "Debug",
      "Microsoft.IdentityModel": "Information"
    }
  }
}

Busque:

[Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:
  Failed to validate the token.
[Debug] Microsoft.IdentityModel.Tokens: IDX10230: Lifetime validation failed.
  The token is expired.

Escenario 2: Errores de adquisición de tokens

Síntoma:MsalServiceException o MsalUiRequiredException

Habilite el registro detallado:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity.Web": "Debug",
      "Microsoft.Identity.Client": "Information"
    }
  }
}

Busque:

[Error] Microsoft.Identity.Web: Token acquisition failed.
  ErrorCode: invalid_grant, CorrelationId: {guid}
[Information] Microsoft.Identity.Client: MSAL returned exception:
  AADSTS50058: Silent sign-in failed.

Escenario 3: Fallos en la llamada a la API descendente

Síntoma: Errores HTTP 502 o de tiempo de espera al llamar a las API descendentes

Habilite el registro detallado:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.Identity.Abstractions": "Debug",
      "System.Net.Http": "Information"
    }
  }
}

Agregue el registro personalizado en el controlador para capturar errores de API de bajada:

[HttpGet]
public async Task<IActionResult> GetUserProfile()
{
    try
    {
        _logger.LogInformation("Acquiring token for Microsoft Graph");

        var user = await _downstreamApi.GetForUserAsync<User>(
            "MicrosoftGraph",
            options => options.RelativePath = "me");

        _logger.LogInformation(
            "Successfully retrieved user profile for {UserPrincipalName}",
            user.UserPrincipalName);

        return Ok(user);
    }
    catch (MsalUiRequiredException ex)
    {
        _logger.LogWarning(ex,
            "User interaction required. CorrelationId: {CorrelationId}",
            ex.CorrelationId);
        return Challenge();
    }
    catch (HttpRequestException ex)
    {
        _logger.LogError(ex, "Failed to call Microsoft Graph API");
        return StatusCode(502, "Downstream API error");
    }
}

Interpretación de patrones de registro

En los ejemplos siguientes se muestra la salida típica del registro para eventos de autenticación comunes.

Flujo de autenticación correcto:

[Info] Authentication scheme OpenIdConnect: Authorization response received
[Debug] Correlation id: {guid}
[Info] Authorization code received
[Info] Token validated successfully
[Info] Authentication succeeded for user: {user}

Consentimiento necesario:

[Warning] Microsoft.Identity.Web: Incremental consent required
[Info] AADSTS65001: User consent is required for scopes: {scopes}
[Info] Redirecting to consent page

Actualización del token:

[Debug] Token expired, attempting silent token refresh
[Info] Token source: IdentityProvider
[Info] Token refreshed successfully

Agregar registros con proveedores externos

Reenvíe los registros de identidad a una plataforma de registro centralizada para la supervisión y las alertas.

Integración de Application Insights:

Envío de telemetría de identidad a Application Insights mediante el enriquecimiento del identificador de correlación.

using Microsoft.ApplicationInsights.Extensibility;

builder.Services.AddApplicationInsightsTelemetry();

// Enrich telemetry with correlation IDs
builder.Services.AddSingleton<ITelemetryInitializer, CorrelationIdTelemetryInitializer>();

Integración de Serilog:

Configure Serilog para capturar registros de identidad en la consola y las salidas graduales de archivos:

using Serilog;

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .MinimumLevel.Override("Microsoft.Identity", Serilog.Events.LogEventLevel.Debug)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.File("logs/identity-.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

builder.Host.UseSerilog();

Siga los procedimientos recomendados de registro.

Aplique estos procedimientos para mantener los registros de identidad seguros, útiles y eficaces.

Qué hacer

1. Uso del registro estructurado:

Pase valores como parámetros con nombre para que los agregadores de registro puedan indexarlos y consultarlos:

_logger.LogInformation(
    "Token acquired for user {UserId} with scopes {Scopes}",
    userId, string.Join(" ", scopes));

2. Registre identificadores de correlación:

Incluya siempre el identificador de correlación en los registros de errores para simplificar las investigaciones de soporte técnico:

_logger.LogError(ex,
    "Operation failed. CorrelationId: {CorrelationId}",
    ex.CorrelationId);

3. Use los niveles de registro adecuados:

Haga coincidir el nivel de registro con la gravedad y la audiencia:

_logger.LogDebug("Detailed diagnostic info");      // Development
_logger.LogInformation("Key application events");  // Selective production
_logger.LogWarning("Unexpected but handled");      // Production
_logger.LogError(ex, "Operation failed");          // Production

4. Sanear registros en producción:

Enmascara los valores confidenciales antes de escribirlos en los registros de producción:

var sanitizedEmail = environment.IsProduction()
    ? MaskEmail(email)
    : email;
_logger.LogInformation("Processing request for {Email}", sanitizedEmail);

Cosas que no debes hacer

1. No habilite PII en producción:

//  Wrong
"EnablePiiLogging": true  // In production config!

//  Correct
"EnablePiiLogging": false

2. No registre secretos:

//  Wrong
_logger.LogInformation("Token: {Token}", accessToken);

//  Correct
_logger.LogInformation("Token acquired, expires: {ExpiresOn}", expiresOn);

3. No use registros detallados en producción:

//  Wrong - production appsettings.json
"Microsoft.Identity": "Debug"

//  Correct
"Microsoft.Identity": "Warning"