簡體   English   中英

HttpClient 403 捕獲過期 API Token.Net Core 3.1

[英]HttpClient 403 Catching Expired API Token .Net Core 3.1

我正在使用的 API Swagger 端點需要我創建一個附加了 Bearer 令牌的 HttpClient。

我這樣做:

public static HttpClient BuildClient(string baseUrl, string username, string password)
    {
        AuthenticationClient client = new AuthenticationClient(new HttpClient())
        {
            BaseUrl = baseUrl
        };

        CreateTokenRequest tokenRequest = new CreateTokenRequest
        {
            Username = username,
            Password = password
        };

        CreateTokenResponse createTokenResponse = client.CreateAsync(tokenRequest).Result;

        HttpClient httpClient;
        HttpClientHandler handler = new HttpClientHandler();
        httpClient = new HttpClient(handler) { BaseAddress = new Uri(baseUrl) };
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", createTokenResponse.Access_token);

        return httpClient;
    }

我的一些代碼運行時間比 Bearer 令牌的壽命長。

是否可以捕獲 403 Forbidden,令牌過期,並在此級別刷新它?

我懷疑,雖然可能完全錯誤,但我應該在自定義 HttpMessageHandler 中實現一些東西,但無法弄清楚如何去做。

public class MyHttpMessageHandler : HttpMessageHandler
{

}

任何指導將不勝感激。

您必須在瀏覽器中處理 403 異常。

只需對 OpenID 服務器進行另一個身份驗證調用,與初始身份驗證請求相同。 如果您仍然在 SSO 服務器上登錄,它只會返回帶有新access_token的響應。

好的 - 這是我的解決方案。

我看到的一個尚未解決的問題是,如果我對 API 進行多線程調用,它會為每個線程調用一個新令牌。

如果您發現它有任何問題,請告訴我?

用途:

using Microsoft.Extensions.Caching.Memory;
using Cloud.API.CloudService;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

代碼:

public class SCHelpers
{
    private static readonly MemoryCache _memoryCache = new MemoryCache(new MemoryCacheOptions());

    public static HttpClient BuildClient(string baseUrl, string username, string password)
    {
        HttpClient httpClient;
        HttpClientHandler handler = new HttpClientHandler();
        httpClient = new HttpClient(new RetryMessageHandler(handler, baseUrl, username, password)) { BaseAddress = new Uri(baseUrl) };
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        return httpClient;
    }

    private static string GetToken(string baseUrl, string username, string password)
    {
        if (!_memoryCache.TryGetValue("Token", out string _))
        {
            AuthenticationClient client = new AuthenticationClient(new HttpClient())
            {
                BaseUrl = baseUrl
            };

            CreateTokenRequest tokenRequest = new CreateTokenRequest
            {
                Username = username,
                Password = password
            };

            CreateTokenResponse tokenResponse = client.CreateAsync(tokenRequest).Result;

            MemoryCacheEntryOptions cacheEntryOptions = new MemoryCacheEntryOptions
            {
                AbsoluteExpiration = DateTime.Now.AddMinutes(15),
                //cacheEntryOptions.AbsoluteExpiration = tokenResponse.Expires;
                SlidingExpiration = TimeSpan.FromMinutes(1)
            };

            _memoryCache.Set("Token", tokenResponse.Access_token, cacheEntryOptions);
        }

        string token = _memoryCache.Get<string>("Token");
        return token;
    }

    public class RetryMessageHandler : DelegatingHandler
    {
        private readonly string _baseUrl;
        private readonly string _password;
        private readonly string _username;
        public RetryMessageHandler(HttpMessageHandler innerhandler, string baseUrl, string username, string password) : base(innerhandler)
        {
            _baseUrl = baseUrl;
            _username = username;
            _password = password;
        }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            string token = GetToken(_baseUrl, _username, _password);
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
            return await base.SendAsync(request, cancellationToken);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM