Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Microsoft. O Identity.Web integra-se com a infraestrutura de registo do ASP.NET Core. Utilize-o para diagnosticar problemas em várias áreas:
- Fluxos de autenticação - Início de sessão, terminação de sessão, validação de tokens
- Aquisição de tokens - Acertos/falhas na cache de tokens, operações MSAL
- Chamadas de API downstream - pedidos HTTP, aquisição de tokens para APIs
- Condições de erro - Exceções, falhas de validação
Compreender componentes registados
| Componente | Origem do Registo | Purpose |
|---|---|---|
| Microsoft.Identity.Web | Lógica de autenticação central | Configuração, aquisição de tokens, chamadas API |
| MSAL.NET | Microsoft.Identity.Client |
Operações de cache de token, validação de autoridade |
| IdentityModel | Validação de token | Análise de JWT, validação de assinaturas, extração de declarações |
| ASP.NET Core Auth | Microsoft.AspNetCore.Authentication |
Operações de cookies, ações de desafio/proibição |
Comece a fazer registos
Configuração mínima
Adicione as seguintes entradas de nível de registo a appsettings.json para permitir o registo de identidade.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity": "Information"
}
}
}
Isto permite registos de nível de informação para Microsoft.Identity.Web e as suas dependências (MSAL.NET, IdentityModel).
Configuração de desenvolvimento
Para diagnósticos detalhados 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
Para produção, minimize o volume de registos 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 espaço de nomes
Controla a verbosidade dos registos por namespace. A seguinte configuração define níveis granulares para cada namespace relacionado com 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"
}
}
}
Desativar registos específicos
Para silenciar componentes ruidosos sem afetar outros, defina o seu nível logarítmico para 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
Uso appsettings.{Environment}.json para definiçõ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
}
}
Compreender os níveis de log
O ASP.NET Core define os seguintes níveis logaritários. Escolha o nível que equilibre o detalhe de diagnóstico contra o volume de registos para o seu ambiente.
Níveis de log ASP.NET Core
| Nível | Usage | Volume | Produção? |
|---|---|---|---|
| Trace | Mais detalhado, em todas as operações | Muito alto | No |
| Debug | Fluxo detalhado, útil para programadores | Alto | No |
| Informações | Fluxo geral, eventos chave | Moderado | Seletiva |
| Warning | Condições inesperadas mas entretanto geridas | Baixo | Sim |
| Erro | Erros e exceções | Muito Baixo | Sim |
| Critical | Falhas irrecuperáveis | Muito Baixo | Sim |
| Nenhum | Desativar o registo de logs | Nenhum | Seletiva |
Mapear MSAL.NET para níveis ASP.NET Core
| Nível MSAL.NET | ASP.NET Core Equivalente | Descrição |
|---|---|---|
Verbose |
Debug ou Trace |
Mensagens mais detalhadas |
Info |
Information |
Eventos de autenticação de chaves |
Warning |
Warning |
Condições anormais mas controladas |
Error |
Error ou Critical |
Erros e exceções |
Aplicar as definições recomendadas por ambiente
Use as seguintes configurações por ambiente.
Desenvolvimento:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Debug",
"Microsoft.Identity.Client": "Information"
}
}
}
Ambiente de Testes:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Information",
"Microsoft.Identity.Client": "Warning"
}
}
}
Produção:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Warning",
"Microsoft.Identity.Client": "Error"
}
}
}
Configurar o registo de PII
Por padrão, o Microsoft.Identity.Web oculta informações de identificação pessoal (PII) dos registos. Ative o registo de PII apenas em ambientes de desenvolvimento para ver todos os detalhes do utilizador.
O que é PII?
A Informação Pessoal Identificável (PII) inclui:
- Nomes de utilizador, endereços de email
- Nomes de exibição
- IDs de objetos, IDs de inquilino
- Endereços IP
- Valores de tokens, reivindicações
Aviso de segurança
AVISO: Você e a sua candidatura são responsáveis por cumprir todos os requisitos regulamentares aplicáveis, incluindo os estabelecidos pelo RGPD. Antes de ativar o registo de PII, certifique-se de que consegue lidar com estes dados potencialmente altamente sensíveis em segurança.
Ativar registo de informações PII (apenas para desenvolvimento)
Defina EnablePiiLogging para true no seu ficheiro de configuração de desenvolvimento:
appsettings.Development.json:
{
"AzureAd": {
"EnablePiiLogging": true // Development/Testing ONLY
},
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Debug"
}
}
}
Controla o registo de PII de forma programática
Alterne o registo das PII com base no ambiente de alojamento:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<MicrosoftIdentityOptions>(options =>
{
// Only enable PII in Development
options.EnablePiiLogging = builder.Environment.IsDevelopment();
});
O que muda com as PII ativadas?
Sem registo de PII:
[Information] Token validation succeeded for user '{hidden}'
[Information] Acquired token from cache for scopes '{hidden}'
Com a PII ativada:
[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 nos registos
Quando o registo de PII está desativado, os dados sensíveis são substituídos por:
-
{hidden}- Oculta identificadores de utilizador -
{hash:XXXX}- Mostra o hash em vez do valor real -
***- Oculta tokens
Usar identificadores de correlação
Os IDs de correlação rastreiam pedidos de autenticação entre serviços. Inclua-os nos registos e nos tickets de suporte para acelerar a resolução de problemas.
O que são IDs de correlação?
Um ID de correlação é um GUID que identifica de forma única um pedido de autenticação ou aquisição de token ao longo de:
- A aplicação
- Plataforma Microsoft Identity
- Biblioteca MSAL.NET
- Serviços backend da Microsoft
Obter IDs de correlação
Método 1: A partir do AuthenticationResult
Extraia o ID de correlação de AuthenticationResult após uma aquisição bem-sucedida do token.
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 o identificador de correlação a partir de MsalServiceException quando a aquisição do token falha.
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 um ID de correlação personalizado
Atribua um ID de correlação personalizado para ligar os rastreios da aplicação aos pedidos do 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);
}
Forneça IDs de correlação para suporte
Quando contactar o suporte da Microsoft, forneça os seguintes detalhes:
- ID de correlação - A partir de logs ou exceção
- Carimbo temporal - Quando ocorreu o erro (UTC)
- ID de Inquilino - O seu inquilino Microsoft Entra ID
-
Código de erro - Se aplicável (por exemplo,
AADSTS50058)
Exemplo de pedido 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
Ativar o registo da cache de tokens
O registo de cache de tokens ajuda-te a compreender o comportamento de acertos/erros da cache e a diagnosticar problemas de desempenho com caches distribuídas.
Ativar diagnósticos de cache de token
Para aplicações .NET Framework ou .NET Core que utilizam caches de tokens distribuídos, configure registos detalhados:
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 registos de cache de tokens
Impacto do cache:
[Debug] Token cache: Token found in cache for scopes 'user.read'
[Information] Token source: Cache
Erro de cache:
[Debug] Token cache: No token found in cache for scopes 'user.read'
[Information] Token source: IdentityProvider
[Debug] Token cache: Token stored in cache
Resolução de problemas de caches distribuídas
Ative o registo específico do fornecedor para diagnosticar problemas de conectividade e desempenho da 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:
Configure a cache distribuída do SQL Server com registo:
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);
});
Resolver problemas comuns
Use os seguintes cenários para diagnosticar problemas frequentes de autenticação e autorização.
Cenários comuns de registo
Cenário 1: Falhas na validação do token
Sintoma: 401 Respostas não autorizadas
Ativar o registo detalhado:
{
"Logging": {
"LogLevel": {
"Microsoft.AspNetCore.Authentication.JwtBearer": "Debug",
"Microsoft.IdentityModel": "Information"
}
}
}
Pesquisar:
[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 na aquisição de tokens
Sintoma:MsalServiceException ou MsalUiRequiredException
Ativar o registo detalhado:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity.Web": "Debug",
"Microsoft.Identity.Client": "Information"
}
}
}
Pesquisar:
[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 nas chamadas de API a jusante
Sintoma: HTTP 502 ou erros de timeout ao chamar APIs a jusante
Ativar o registo detalhado:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity.Abstractions": "Debug",
"System.Net.Http": "Information"
}
}
}
Adicione login personalizado no seu controlador para capturar erros da API a jusante:
[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 logarítmicos
Os exemplos seguintes mostram a saída típica de registo 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 do token:
[Debug] Token expired, attempting silent token refresh
[Info] Token source: IdentityProvider
[Info] Token refreshed successfully
Agregar registos junto a fornecedores externos
Encaminhe os registos de identidade para uma plataforma centralizada de registo para monitorização e alerta.
Integração com o Application Insights:
Envie telemetria de identidade para 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 com Serilog:
Configure o Serilog para capturar registos de identidade para as saídas de ficheiros da consola e roll:
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 melhores práticas de registo de logs
Aplique estas práticas para manter os seus registos de identidade seguros, úteis e eficazes.
Coisas a Fazer
1. Utilizar registo estruturado:
Passe valores como parâmetros nomeados para que os agregadores de logs 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 logarítmica:
Inclua sempre o ID de correlação nos registos de erro para simplificar investigações de suporte:
_logger.LogError(ex,
"Operation failed. CorrelationId: {CorrelationId}",
ex.CorrelationId);
3. Use níveis logarítmicos apropriados:
Ajusta o nível do log à gravidade 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. Limpar registos em produção:
Mascarar valores sensíveis antes de os escrever nos registos de produção:
var sanitizedEmail = environment.IsProduction()
? MaskEmail(email)
: email;
_logger.LogInformation("Processing request for {Email}", sanitizedEmail);
Coisas a não fazer
1. Não ative Informações de Identificação Pessoal (PII) em produção:
// Wrong
"EnablePiiLogging": true // In production config!
// Correct
"EnablePiiLogging": false
2. Não registar segredos:
// Wrong
_logger.LogInformation("Token: {Token}", accessToken);
// Correct
_logger.LogInformation("Token acquired, expires: {ExpiresOn}", expiresOn);
3. Não use registo verboso em produção:
// Wrong - production appsettings.json
"Microsoft.Identity": "Debug"
// Correct
"Microsoft.Identity": "Warning"