Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Microsoft.Identity.Web интегрируется с инфраструктурой логирования ASP.NET Core. Используйте его для диагностики проблем в разных странах:
- Потоки проверки подлинности — вход, выход, проверка маркеров
- Получение токена — попадания и промахи кэша токенов, операции MSAL
- Вызовы дочернего API — HTTP-запросы, получение токенов для API
- Условия ошибки — исключения, сбои проверки
Общие сведения о зарегистрированных компонентах
| Компонент | Источник журнала событий | Purpose |
|---|---|---|
| Microsoft. Identity.Web | Основная логика проверки подлинности | Конфигурация, получение токена, вызовы API |
| MSAL.NET | Microsoft.Identity.Client |
Операции кэша токенов, проверка полномочий |
| Модель идентичности | Проверка токенов | Анализ JWT, проверка подписи, извлечение утверждений |
| ASP.NET Core Auth | Microsoft.AspNetCore.Authentication |
Операции cookie, вызовы и запреты действий |
Как начать работать с логированием
Минимальная конфигурация
Чтобы включить логирование идентификации, добавьте следующие записи уровня журнала в appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity": "Information"
}
}
}
Это позволяет Information-level логирование для Microsoft.Identity.Web и его зависимостей (MSAL.NET, IdentityModel).
Конфигурация разработки
Для подробной диагностики во время разработки:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Identity": "Debug",
"Microsoft.AspNetCore.Authentication": "Information"
}
},
"AzureAd": {
"EnablePiiLogging": true // Development only!
}
}
Рабочая конфигурация
Для рабочей среды свести к минимуму объем журнала при записи ошибок:
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Identity": "Warning"
}
},
"AzureAd": {
"EnablePiiLogging": false // Never true in production
}
}
Настройка фильтрации журналов
Фильтрация на основе пространства имен
Управление уровнем детализации логов по пространству имен. Для каждого пространства имен, связанного с идентификацией, устанавливаются следующие уровни конфигурации:
{
"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"
}
}
}
Отключение определенного ведения журнала
Чтобы отключить шумные компоненты, не затрагивая другие, задайте для их уровня журнала значение None или Warning.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "None", // Completely disable
"Microsoft.Identity.Client": "Warning" // Only errors/warnings
}
}
}
Конфигурация для конкретной среды
Используйте appsettings.{Environment}.json для установки параметров для каждой среды.
appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Debug"
}
},
"AzureAd": {
"EnablePiiLogging": true
}
}
appsettings.Production.json:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Warning"
}
},
"AzureAd": {
"EnablePiiLogging": false
}
}
Понять уровни журнала
ASP.NET Core определяет следующие уровни журнала. Выберите уровень, который балансирует данные диагностики с объемом журнала для вашей среды.
уровни логирования ASP.NET Core
| Уровень | Использование | Объем | Производственный процесс? |
|---|---|---|---|
| Трассировка | Подробно описана каждая операция | Очень высокий | Нет |
| Debug | Подробный поток, полезный для разработки | Высокий | Нет |
| Информация | Общий поток, ключевые события | Умеренно | Выборочный |
| Предупреждение | Непредвиденные, но обрабатываемые условия | Низкий | Да |
| Error | Ошибки и исключения | Очень низкий | Да |
| Критический | Неустранимые сбои | Очень низкий | Да |
| Нет | Отключение ведения журнала | Нет | Выборочный |
Соотнесение MSAL.NET с уровнями ASP.NET Core
| уровень MSAL.NET | эквивалент ASP.NET Core | Описание |
|---|---|---|
Verbose |
Debug или Trace |
Наиболее подробные сообщения |
Info |
Information |
События проверки подлинности ключей |
Warning |
Warning |
Аномальные, но обрабатываемые условия |
Error |
Error или Critical |
Ошибки и исключения |
Применение рекомендуемых параметров по среде
Используйте следующие конфигурации для каждой среды.
Разработка:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Debug",
"Microsoft.Identity.Client": "Information"
}
}
}
Стейджинг:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Information",
"Microsoft.Identity.Client": "Warning"
}
}
}
Производства:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Warning",
"Microsoft.Identity.Client": "Error"
}
}
}
Настройка логирования персональных данных
По умолчанию Microsoft. Identity.Web редактирует персональные данные (PII) из журналов. Включите ведение журнала PII только в средах разработки, чтобы просмотреть полные сведения о пользователе.
Что такое PII?
Личные сведения (PII) включают:
- Имена пользователей, адреса электронной почты
- Отображаемые имена
- Идентификаторы объектов, идентификаторы клиента
- IP-адреса
- Значения маркеров, утверждения
Предупреждение системы безопасности
ПРЕДУПРЕЖДЕНИЕ. Вы и ваше приложение отвечают за соблюдение всех применимых нормативных требований, включая те, которые определены GDPR. Перед включением ведения журнала piI убедитесь, что вы можете безопасно обрабатывать эти потенциально конфиденциальные данные.
Включение ведения журнала PII (только для разработки)
Задайте значение EnablePiiLoggingtrue в файле конфигурации разработки:
appsettings.Development.json:
{
"AzureAd": {
"EnablePiiLogging": true // Development/Testing ONLY
},
"Logging": {
"LogLevel": {
"Microsoft.Identity": "Debug"
}
}
}
Управление логированием PII программным способом
Переключение логирования PII в зависимости от среды размещения:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<MicrosoftIdentityOptions>(options =>
{
// Only enable PII in Development
options.EnablePiiLogging = builder.Environment.IsDevelopment();
});
Какие изменения происходят при включении PII?
Без ведения журнала PII:
[Information] Token validation succeeded for user '{hidden}'
[Information] Acquired token from cache for scopes '{hidden}'
С включенным piI:
[Information] Token validation succeeded for user 'john.doe@contoso.com'
[Information] Acquired token from cache for scopes 'user.read api://my-api/.default'
Редактура PII в журналах
При отключении ведения журнала piI конфиденциальные данные заменяются следующим образом:
-
{hidden}— скрывает идентификаторы пользователей -
{hash:XXXX}— отображает хэш вместо фактического значения -
***— скрывает токены
Использование идентификаторов корреляции
Идентификаторы корреляции используются для отслеживания запросов аутентификации между различными службами. Включите их в журналы и запросы в службу поддержки, чтобы ускорить разрешение проблем.
Что такое идентификаторы корреляции?
Идентификатор корреляции — это идентификатор GUID , который однозначно идентифицирует запрос на проверку подлинности или получение маркеров по всему:
- Ваше приложение
- платформа удостоверений Microsoft
- библиотека MSAL.NET
- серверные службы Microsoft
Получение идентификаторов корреляции
Метод 1: из AuthenticationResult
Извлеките идентификатор корреляции из AuthenticationResult после успешного получения токена.
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);
}
}
Метод 2: от MsalServiceException
Зафиксировать идентификатор корреляции при MsalServiceException сбое получения маркера:
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
});
}
Метод 3. Настройка пользовательского идентификатора корреляции
Назначьте пользовательский идентификатор корреляции для связывания трассировок приложений с запросами 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);
}
Предоставление идентификаторов корреляции для поддержки
При обращении к Microsoft поддержке укажите следующие сведения:
- Идентификатор корреляции — из журналов или исключений
- Метка времени — при возникновении ошибки (UTC)
- идентификатор Tenant ID — клиент Microsoft Entra ID
-
Код ошибки : если применимо (например,
AADSTS50058)
Пример запроса на поддержку:
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
Включить журналирование кэша токенов
Ведение журнала кэша токенов помогает понять поведение попаданий/промахов кэша и диагностировать проблемы с производительностью распределенных кэшей.
Включить диагностику кэша токенов
Для приложений .NET Framework или .NET Core с помощью распределенных кэшей маркеров настройте подробное ведение журнала:
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
});
Примеры логов кэша токенов
Попадание в кэш:
[Debug] Token cache: Token found in cache for scopes 'user.read'
[Information] Token source: Cache
Промах кэша:
[Debug] Token cache: No token found in cache for scopes 'user.read'
[Information] Token source: IdentityProvider
[Debug] Token cache: Token stored in 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:
Настройка распределенного кэша SQL Server с ведением журнала:
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);
});
Устранение распространенных неполадок
Используйте следующие сценарии для диагностики частых проблем проверки подлинности и авторизации.
Распространенные сценарии ведения журнала
Сценарий 1: Ошибки проверки токенов
Симптом: 401 Несанкционированные ответы
Включите подробное ведение журнала:
{
"Logging": {
"LogLevel": {
"Microsoft.AspNetCore.Authentication.JwtBearer": "Debug",
"Microsoft.IdentityModel": "Information"
}
}
}
Ищите:
[Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:
Failed to validate the token.
[Debug] Microsoft.IdentityModel.Tokens: IDX10230: Lifetime validation failed.
The token is expired.
Сценарий 2: Ошибки получения токена
Симптом:MsalServiceException Или MsalUiRequiredException
Включите подробное ведение журнала:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity.Web": "Debug",
"Microsoft.Identity.Client": "Information"
}
}
}
Ищите:
[Error] Microsoft.Identity.Web: Token acquisition failed.
ErrorCode: invalid_grant, CorrelationId: {guid}
[Information] Microsoft.Identity.Client: MSAL returned exception:
AADSTS50058: Silent sign-in failed.
Сценарий 3. Сбои вызовов низкоуровневого API
Симптом: Ошибки HTTP 502 или ошибки времени ожидания при вызове нижестоящего API
Включите подробное ведение журнала:
{
"Logging": {
"LogLevel": {
"Microsoft.Identity.Abstractions": "Debug",
"System.Net.Http": "Information"
}
}
}
Добавьте настраиваемое ведение журнала в контроллер для записи ошибок нижестоящего API:
[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");
}
}
Интерпретация шаблонов журналов
В следующих примерах показаны типичные выходные данные журнала для распространенных событий проверки подлинности.
Успешный поток проверки подлинности:
[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}
Требуется согласие:
[Warning] Microsoft.Identity.Web: Incremental consent required
[Info] AADSTS65001: User consent is required for scopes: {scopes}
[Info] Redirecting to consent page
Обновление токена:
[Debug] Token expired, attempting silent token refresh
[Info] Token source: IdentityProvider
[Info] Token refreshed successfully
Агрегировать журналы регистрации у внешних поставщиков услуг.
Переадресация идентификационных журналов в централизованную платформу логирования для мониторинга и оповещения.
Интеграция с Application Insights:
Отправка телеметрии идентификационных данных в Application Insights с обогащением идентификаторов корреляции:
using Microsoft.ApplicationInsights.Extensibility;
builder.Services.AddApplicationInsightsTelemetry();
// Enrich telemetry with correlation IDs
builder.Services.AddSingleton<ITelemetryInitializer, CorrelationIdTelemetryInitializer>();
Интеграция Serilog:
Настройте Serilog для записи журналов удостоверений в консоль и последовательного вывода файлов:
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();
Следуйте рекомендациям по ведению журнала
Примените эти методики, чтобы обеспечить безопасность, полезность и производительность журналов удостоверений.
Что нужно делать
1. Используйте структурированное ведение журнала:
Передайте значения в качестве именованных параметров, чтобы агрегаторы журналов могли индексировать и запрашивать их:
_logger.LogInformation(
"Token acquired for user {UserId} with scopes {Scopes}",
userId, string.Join(" ", scopes));
2. Идентификаторы корреляции журналов:
Всегда включать идентификатор корреляции в журналы ошибок, чтобы упростить исследования поддержки:
_logger.LogError(ex,
"Operation failed. CorrelationId: {CorrelationId}",
ex.CorrelationId);
3. Используйте соответствующие уровни журналов:
Соотнесите уровень логирования с серьезностью и аудиторией:
_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. Очистка журналов в рабочей среде:
Маскировать конфиденциальные значения перед записью в рабочие журналы:
var sanitizedEmail = environment.IsProduction()
? MaskEmail(email)
: email;
_logger.LogInformation("Processing request for {Email}", sanitizedEmail);
Чего не следует делать
1. Не включайте персонально идентифицируемые данные в рабочей среде:
// Wrong
"EnablePiiLogging": true // In production config!
// Correct
"EnablePiiLogging": false
2. Не записывайте секреты:
// Wrong
_logger.LogInformation("Token: {Token}", accessToken);
// Correct
_logger.LogInformation("Token acquired, expires: {ExpiresOn}", expiresOn);
3. Не используйте подробное ведение журнала в рабочей среде:
// Wrong - production appsettings.json
"Microsoft.Identity": "Debug"
// Correct
"Microsoft.Identity": "Warning"