using System.Net.Http.Headers; namespace Tnsu.ApprovalRoute.Infrastructure.TnsuPortal; /// /// Авторизация запросов к api.tnsu.kz. Вынесена из HttpTnsuPortalClient, потому что /// к порталу ходит не только справочник сотрудников (см. /// HttpSharePointWebhookSubscriber), а правило выбора токена должно быть одно. /// /// Токен берётся в двух режимах, и порядок принципиален: /// 1) Токен вызывающего пользователя (см. TnsuPortalCallerToken) — из текущего /// HTTP-запроса либо переданный аргументом в фоновую задачу. Портал тогда /// видит исходного пользователя, а не сервисное приложение. /// 2) Его нет вовсе — client_credentials самого сервиса (см. /// TnsuPortalTokenProvider). /// /// ВАЖНО про второй путь: TnsuPortal:ClientSecret/Scope в конфигурации пусты /// (см. appsettings.json), поэтому он сейчас нерабочий — это именно фолбэк, а не /// штатный режим. Вызывающая сторона обязана это учитывать: см. /// HttpSharePointWebhookSubscriber, где сбой подписки намеренно не рушит /// провижининг списка. /// public sealed class TnsuPortalAuthorizer( TnsuPortalCallerToken callerToken, TnsuPortalTokenProvider tokenProvider) { public async Task AuthorizeAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var caller = callerToken.Current; if (!string.IsNullOrWhiteSpace(caller)) { request.Headers.TryAddWithoutValidation("Authorization", caller); return; } var token = await tokenProvider.GetAccessTokenAsync(cancellationToken); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); } }