Configure o registro em log no Microsoft. Identity.Web

Microsoft.Identity.Web integra-se à infraestrutura de registros do ASP.NET Core. Use-o para diagnosticar problemas em:

  • Fluxos de autenticação – Entrada, saída, validação de token
  • Aquisição de token – acertos/falhas no cache de token, operações MSAL
  • Chamadas à API downstream – solicitações HTTP, aquisição de token para APIs
  • Condições de erro – exceções, falhas de validação

Entender os componentes registrados

Componente Origem do log Propósito
Microsoft. Identity.Web Lógica de autenticação principal Configuração, aquisição de token, chamadas à API
MSAL.NET Microsoft.Identity.Client Operações de cache de token, validação de autoridade
IdentityModel Validação de token Análise JWT, validação de assinatura, extração de declarações
ASP.NET Core Autenticação Microsoft.AspNetCore.Authentication Operações de cookie, ações de desafio/proibição

Introdução ao registro em log

Configuração mínima

Adicione as seguintes entradas de nível de log para appsettings.json habilitar o registro de identidade:

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

Isso habilita o registro em log Information-level para Microsoft.Identity.Web e suas dependências (MSAL.NET, IdentityModel).

Configuração de desenvolvimento

Para diagnóstico detalhado durante o desenvolvimento:

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

Configuração de produção

Em ambiente de produção, minimize o volume de log ao capturar erros.

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

Configurar a filtragem de logs

Filtragem baseada em namespace

Controlar a verbosidade do log por namespace. A configuração a seguir define níveis granulares para cada namespace relacionado à identidade:

{
  "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"
    }
  }
}

Desabilitar log específico

Para silenciar componentes barulhentos sem afetar outras pessoas, defina seu nível de log como None ou Warning:

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

Configuração específica do ambiente

Use appsettings.{Environment}.json para configurações por ambiente:

appsettings.Development.json:

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

appsettings.Production.json:

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

Entender os níveis de log

ASP.NET Core define os seguintes níveis de log. Escolha o nível que equilibra os detalhes de diagnóstico em relação ao volume de log do seu ambiente.

Níveis de log do ASP.NET Core

Nível Usage Volume Produção?
Trace Mais detalhado, em cada operação. Muito alto No
Depurar Fluxo detalhado, útil para desenvolvimento Alto No
Informação Fluxo geral, principais eventos Moderado Seletiva
Aviso Condições inesperadas, mas tratadas Baixo Sim
Erro Erros e exceções Muito Baixo Sim
Crítico Falhas irrecuperáveis Muito Baixo Sim
Nenhum Desabilitar o registro em log Nenhum Seletiva

Mapear MSAL.NET para níveis de ASP.NET Core

Nível de MSAL.NET ASP.NET Core Equivalente Descrição
Verbose Debug ou Trace Mensagens mais detalhadas
Info Information Principais eventos de autenticação
Warning Warning Condições anormais, mas tratadas
Error Error ou Critical Erros e exceções

Use as configurações a seguir por ambiente.

Desenvolvimento:

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

Staging:

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

Produção:

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

Configurar o log de PII

Por padrão, Microsoft.Identity.Web omite informações de identificação pessoal (PII) dos logs. Habilite o log de PII somente em ambientes de desenvolvimento para ver detalhes completos do usuário.

O que é PII?

As INFORMAÇÕES de Identificação Pessoal (PII) incluem:

  • Nomes de usuário, endereços de email
  • Nomes de exibição
  • IDs de objeto, IDs de locatário
  • Endereços IP
  • Valores de token, declarações

Aviso de segurança

AVISO: você e seu aplicativo são responsáveis por cumprir todos os requisitos regulatórios aplicáveis, incluindo aqueles definidos pelo RGPD. Antes de habilitar o registro em log de PII, verifique se você pode lidar com segurança com esses dados potencialmente altamente confidenciais.

Habilitar registro em log de PII (apenas para desenvolvimento)

Defina EnablePiiLogging para true no arquivo de configuração de desenvolvimento:

appsettings.Development.json:

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

Controlar o registro em log de PII programaticamente

Alterne a ativação do registro de PII com base no ambiente de hospedagem.

var builder = WebApplication.CreateBuilder(args);

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

Quais são as mudanças quando a PII (Informações de Identificação Pessoal) está habilitada?

Sem registro de PII:

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

Com o PII habilitado:

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

Redação de PII em logs

Quando o log de PII está desabilitado, os dados confidenciais são substituídos por:

  • {hidden} - Oculta identificadores de usuário
  • {hash:XXXX} - Mostra o hash em vez do valor real
  • *** - Obscurece tokens (fichas)

Usar IDs de correlação

IDs de correlação rastreiam solicitações de autenticação entre serviços. Inclua-os em logs e tíquetes de suporte para acelerar a resolução de problemas.

O que são IDs de correlação?

Uma ID de correlação é um GUID que identifica exclusivamente uma solicitação de autenticação ou aquisição de token em:

  • Seu aplicativo
  • plataforma Microsoft Identity
  • biblioteca MSAL.NET
  • Serviços de back-end da Microsoft

Obter IDs de correlação

Método 1: A partir de AuthenticationResult

Extraia o ID de correlação de AuthenticationResult após uma aquisição de token bem-sucedida.

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: De MsalServiceException

Capture o ID de correlação de MsalServiceException quando a aquisição do token falhar:

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: Definir uma ID de correlação personalizada

Atribua uma ID de correlação personalizada para vincular rastreamentos de aplicativo com solicitações 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);
}

Fornecer IDs de correlação para suporte

Ao entrar em contato com Microsoft suporte, forneça os seguintes detalhes:

  1. ID de correlação – De registros ou exceções
  2. Carimbo de data e hora - Quando o erro ocorreu (UTC)
  3. Tenant ID - do seu Tenant ID do Microsoft Entra ID
  4. Código de erro - Se aplicável (por exemplo, AADSTS50058)

Exemplo de solicitação de suporte:

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

Habilitar o registro em cache de token

O registro de cache de tokens auxilia a entender o comportamento de acertos e falhas do cache e a diagnosticar problemas de desempenho com caches distribuídos.

Habilitar o diagnóstico de cache de token

Para aplicativos .NET Framework ou .NET Core usando caches de tokens distribuídos, configure o logging detalhado.

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

Exemplos de log de cache de token

Acerto de cache:

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

Falta no cache:

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

Solucionar problemas de caches distribuídos

Habilite o registro em log específico do provedor para diagnosticar problemas de desempenho e conectividade de cache.

Cache Redis:

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 cache distribuído do SQL Server com log de registro:

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 comuns

Use os cenários a seguir para diagnosticar problemas frequentes de autenticação e autorização.

Cenários comuns de log

Cenário 1: falhas de validação de token

Sintoma: 401 Respostas não autorizadas

Habilite o registro em log detalhado:

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

Procurar por:

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

Cenário 2: falhas de aquisição de token

Sintoma:MsalServiceException Ou MsalUiRequiredException

Habilite o registro em log detalhado:

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

Procurar por:

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

Cenário 3: falhas de chamada de API downstream

Sintoma: erros HTTP 502 ou erros de tempo limite ao chamar APIs a jusante

Habilite o registro em log detalhado:

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

Adicione o log personalizado no controlador para capturar erros de API downstream:

[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");
    }
}

Interpretar padrões de log

Os exemplos a seguir mostram a saída de log típica para eventos comuns de autenticação.

Fluxo de autenticação bem-sucedido:

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

Consentimento necessário:

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

Atualização de token:

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

Agregar registros com provedores externos

Encaminhe logs de identidade para uma plataforma centralizada de log para monitoramento e emissão de alertas.

Integração do Application Insights:

Enviar telemetria de identidade para o Application Insights com enriquecimento de ID de correlação:

using Microsoft.ApplicationInsights.Extensibility;

builder.Services.AddApplicationInsightsTelemetry();

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

Integração do Serilog:

Configure o Serilog para capturar logs de identidade para saídas de console e arquivos rotativos.

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 as práticas recomendadas de registro

Aplique essas práticas para manter seus logs de identidade seguros, úteis e com desempenho.

O que fazer

1. Use registro em log estruturado:

Passe valores como parâmetros nomeados para que os agregadores de log possam indexá-los e consultá-los:

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

2. IDs de correlação de log:

Sempre inclua a ID de correlação nos logs de erros para simplificar as investigações de suporte:

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

3. Use os níveis de log apropriados:

Corresponda o nível de log à severidade e ao público:

_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. Sanitizar logs na produção:

Mascarar valores confidenciais antes de escrevê-los nos logs de produção:

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

O que não fazer

1. Não habilite a PII na produção:

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

//  Correct
"EnablePiiLogging": false

2. Não registre segredos:

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

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

3. Não use o log detalhado na produção:

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

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