Запустить поток входа в Identity Server 4 при работе с недействительными ответами - PullRequest
0 голосов
/ 15 января 2020

Из замечательного курса Кевина в Pluralsight - Использование HttpClient для использования API в NET Core ....

У меня есть только сомнения по поводу того, как вызвать поток входа в Identity Server 4 при работе с недопустимым ответы внутри службы клиента http.

Просто упомяните, что, как предложил Кевин, мне удалось создать обработчик делегирования аутентификации, который установит правильный токен-носитель в запросе сообщения http-запроса.

Я хотел бы добавить новый делегирующий обработчик для запуска потока входа в систему Identity Server 4 в случае, если код статуса http не авторизован.

Кажется, что более кратким является добавление дополнительной ответственности к клиентской службе http.

Что делать ты думаешь? Это можно сделать?. Заранее спасибо.

(Ниже я публикую код клиентской службы http, а также обработчика делегирования аутентификации и соответствующей конфигурации запуска)

Краткий код запуска

services
    .AddSingleton<IClientAuthenticationOptions>(new ClientAuthenticationOptions
    {
        Authority = "http.....",

        ClientId = "Game",
        ClientSecret = "secret"
    });

services
    .AddTransient<AuthenticationDelegatingHandler>();

services
    .AddHttpClient()
    .AddHttpClient<IBaseHttpClient, BaseHttpClient>(client =>
    {
        client.BaseAddress = new Uri("http...);
    }) 
    .AddHttpMessageHandler<AuthenticationDelegatingHandler>()
    .ConfigurePrimaryHttpMessageHandler(handler => new HttpClientHandler
    {
        AutomaticDecompression = DecompressionMethods.GZip
    });

Http-клиент службы

using Marvin.StreamExtensions;
using Shared.Asp.Interfaces;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Shared.Asp.Helpers
{
    public class BaseHttpClient : IBaseHttpClient
    {
        private readonly HttpClient _httpClient;
        private readonly CancellationTokenSource _cancellationTokenSource;

        public BaseHttpClient(HttpClient httpClient)
        {
            _httpClient = httpClient;
            _cancellationTokenSource = new CancellationTokenSource();
            _httpClient.DefaultRequestHeaders.Accept.Clear();
        }

        public async Task<T> GetAsync<T>(string requestUri)
        {
            using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
            using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancellationTokenSource.Token);

            if (!response.IsSuccessStatusCode) // inspect the status code
            {

                if (response.StatusCode == HttpStatusCode.Unauthorized)
                    DO SOMETHING HERE TO TRIGGER THE LOGIN FLOW  OR USE OTHER DelegatingHandler FOR SO;

                response.EnsureSuccessStatusCode();
            }

            var stream = await response.Content.ReadAsStreamAsync();
            return await stream.ReadAndDeserializeFromJsonAsync<T>();
        }
    }
}

Обработчик делегирования аутентификации

using IdentityModel.Client;
using Microsoft.AspNetCore.Http;
using Shared.Abs.Interfaces;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using static Shared.Asp.Extensions.HttpClientExtensions;

namespace Shared.Asp.DelegatingHandlers
{
    public class AuthenticationDelegatingHandler : DelegatingHandler
    {
        private readonly HttpClient _httpClient;
        private readonly IHttpContextAccessor _contextAccessor;
        private readonly IClientAuthenticationOptions _authenticationOptions;

        public AuthenticationDelegatingHandler(IHttpClientFactory clientFactory, IHttpContextAccessor contextAccessor, IClientAuthenticationOptions authenticationOptions)
        {
            _contextAccessor = contextAccessor;
            _authenticationOptions = authenticationOptions;

            _httpClient = clientFactory.CreateClient();
        }

        public AuthenticationDelegatingHandler(HttpMessageHandler innerHandler, IHttpClientFactory clientFactory, IHttpContextAccessor contextAccessor, IClientAuthenticationOptions authenticationOptions)
        : base(innerHandler)
        {
            _contextAccessor = contextAccessor;
            _authenticationOptions = authenticationOptions;

            _httpClient = clientFactory.CreateClient();
        }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var accessToken = await _httpClient.GetAccessTokenAsync(_contextAccessor.HttpContext, _authenticationOptions);

            request.SetBearerToken(accessToken);

           return await base.SendAsync(request, cancellationToken);
        }
    }
}

Метод таможенного расширения _httpClient .GetAccessTokenAsyn c (_ contextAccessor.HttpContext, _authenticationOptions) обрабатывает обновление токена ... (не включено для краткости)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...