Получение службы с ограниченной областью действия в пользовательском обработчике делегирования на Blazor Server.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Получение службы с ограниченной областью действия в пользовательском обработчике делегирования на Blazor Server.

Сообщение Anonymous »

Я пытаюсь настроить наше серверное приложение Blazor на использование специального обработчика делегирования, который будет прикреплять токен носителя ко всем исходящим запросам к нашим API. Обработчик делегирования использует службу токенов, которая обрабатывает получение токена, а также процесс его обновления, если срок его действия истек. Код выглядит следующим образом:

Код: Выделить всё

public class HttpAuthorizationHandler : DelegatingHandler
{
private ITokenService _tokenService { get; set; }

public HttpAuthorizationHandler(ITokenService tokenService)
{
_tokenService = tokenService;
}

protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = await _tokenService.TryGetToken();

request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", token);

return await base.SendAsync(request, cancellationToken);
}
}
Я зарегистрировал службу токенов как службу с ограниченной областью в Startup.cs, понимая, что один и тот же экземпляр службы будет оставаться активным в контейнере DI в течение всего срока действия запроса. . Если я правильно понимаю, это означает, что я могу таким образом назначить значения токенов службе на моей странице App.razor и получить их при любом последующем вызове службы токенов:

Код: Выделить всё

@code {
[Parameter]
public string AccessToken { get; set; }
[Parameter]
public string RefreshToken { get; set; }

[Inject] private ITokenService _tokenService { get; set; }

protected override void OnInitialized()
{
_tokenService.AccessToken = AccessToken.NullIfEmpty() ?? _tokenService.AccessToken;
_tokenService.RefreshToken = RefreshToken.NullIfEmpty() ?? _tokenService.RefreshToken;
}
Кажется, это работает нормально для всего, кроме обработчика делегирования — значения прекрасно отображаются в конфигурации с ограниченной областью для любого другого запроса, сделанного к службе токенов. , но при внедрении службы токенов в обработчик делегирования значение токена всегда становится нулевым.
Изображение

Неудивительно, что если я зарегистрирую службу как синглтон, значения прекрасно передаются обработчику делегирования , но это явно не решение. По какой-то причине область DI для обработчика отличается от области остального приложения, и я понятия не имею, почему. Есть идеи? Заранее благодарен за помощь.
РЕДАКТИРОВАТЬ
С некоторой помощью Просто Геда и Эндрю Лока я смог подойдите немного ближе, используя IHttpContextAccessor, чтобы получить экземпляр ITokenService, связанный с запросом. Я был в восторге, когда впервые вошел в систему и увидел, что это работает, но как только мое волнение улеглось, я заметил, что через некоторое время он перестает работать правильно. Оказывается, этот метод синхронизирует экземпляры только при первоначальном запросе — по истечении этого времени срабатывает неуклюжее управление конвейером DI и поддерживает один и тот же экземпляр службы для каждого последующего запроса, и все они снова теряют согласованность. Вот пример журналов отладки моего тестирования:

Код: Выделить всё

App.razor:         e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
AuthStateProvider: e12f6c80-5cee-44a0-a8a0-d6b783057339 ├ Initial request - all IDs match
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ├ Clicking around a bunch
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
App.razor:         cab70e54-1907-462d-8918-dbd771fabe76 ┐
AuthStateProvider: cab70e54-1907-462d-8918-dbd771fabe76 ├ Load a new page - ah, crap...
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
App.razor:         3c55ff9c-5511-40a1-9fb8-cd00f9fc11c6 │
AuthStateProvider: 3c55ff9c-5511-40a1-9fb8-cd00f9fc11c6 ├ Dang it all to heck
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
Отличная запись в блоге Эндрю Лока на эту тему содержит очень полезные подробности о том, почему происходят подобные вещи - по-видимому, внедрение зависимостей управляет временем жизни конвейеров HTTP-запросов отдельно от времени жизни сами HTTP-клиенты, поэтому вы не можете полагаться на то, что конвейер является частью того же контекста, что и запрос. Он предлагает использовать IHttpContextAccessor в качестве решения этой проблемы, но, похоже, в данном конкретном случае это не решает проблему. Я подозреваю, что его сообщение в блоге относится к более ранней версии ASP.NET Core, поведение которой неприменимо к приложениям Blazor. Фактически, как отметил Алекс, Microsoft специально не рекомендует использовать IHttpContextAccessor для общего состояния.

Подробнее здесь: https://stackoverflow.com/questions/698 ... zor-server
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»