pcut_uwp/PCUT/Http.Core/Handlers/AuthenticationHandler.cs

69 lines
2.5 KiB
C#

using Http.Core.Constants;
using Http.Core.Contexts;
using Http.Core.Extensions;
using Http.Core.Models;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
namespace Http.Core.Handlers
{
public class AuthenticationHandler : DelegatingHandler
{
public static readonly TimeSpan _requiredRefreshTime = TimeSpan.FromMinutes(5);
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var shouldContinue = await AppendTokenAsync(request);
if (!shouldContinue)
return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
return await base.SendAsync(request, cancellationToken);
}
private static readonly SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1);
private async Task<bool> AppendTokenAsync(HttpRequestMessage request)
{
if (request.Headers.Authorization == null)
{
if (UserContext.Instance.AccessToken == null)
return false;
var expiredTime = UserContext.Instance.ExpiredTime;
if (expiredTime != null || expiredTime - DateTime.UtcNow < _requiredRefreshTime)
{
await _refreshSemaphore.WaitAsync();
bool refreshSuccess;
{
expiredTime = UserContext.Instance.ExpiredTime;
if (expiredTime != null || expiredTime - DateTime.UtcNow < _requiredRefreshTime)
refreshSuccess = await RefreshTokenAsync();
else
refreshSuccess = true; // Some other thread already refreshed token
}
_refreshSemaphore.Release();
if (!refreshSuccess)
return false;
}
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", UserContext.Instance.AccessToken);
return true;
}
return true;
}
private async Task<bool> RefreshTokenAsync()
{
try
{
using (var client = HttpClientFactory.CreateClient(HttpConstants.ClientNames.AuthClient))
{
return await client.RefreshTokenAsync();
}
}
catch { }
return false;
}
}
}