108 lines
4.9 KiB
C#
108 lines
4.9 KiB
C#
using System.Net;
|
|
using System.Text.Json;
|
|
using System.Text;
|
|
|
|
using MesaFabApproval.Shared.Models;
|
|
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using System.Net.Http.Headers;
|
|
using MesaFabApproval.Client.Services;
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
namespace MesaFabApproval.Client.Utilities;
|
|
|
|
public class ApiHttpClientHandler : DelegatingHandler {
|
|
private readonly IMemoryCache _cache;
|
|
private readonly IAuthenticationService _authService;
|
|
private readonly MesaFabApprovalAuthStateProvider _authStateProvider;
|
|
private readonly NavigationManager _navigationManager;
|
|
|
|
private readonly string _apiBaseUrl;
|
|
|
|
public ApiHttpClientHandler(IMemoryCache cache,
|
|
IConfiguration config,
|
|
IAuthenticationService authService,
|
|
MesaFabApprovalAuthStateProvider authStateProvider,
|
|
NavigationManager navigationManager) {
|
|
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
|
|
_apiBaseUrl = config["FabApprovalApiBaseUrl"] ??
|
|
throw new NullReferenceException("FabApprovalApiBaseUrl not found in config");
|
|
_authService = authService ??
|
|
throw new ArgumentNullException("IAuthenticationService not injected");
|
|
_authStateProvider = authStateProvider ??
|
|
throw new ArgumentNullException("MesaFabApprovalAuthStateProvider not injected");
|
|
_navigationManager = navigationManager ??
|
|
throw new ArgumentNullException("NavigationManager not injected");
|
|
}
|
|
|
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage,
|
|
CancellationToken cancellationToken) {
|
|
AuthTokens? authTokens = await _authService.GetAuthTokens();
|
|
|
|
if (authTokens is not null) requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authTokens.JwtToken);
|
|
|
|
HttpResponseMessage responseMessage = await base.SendAsync(requestMessage, cancellationToken);
|
|
|
|
if (responseMessage.StatusCode.Equals(HttpStatusCode.Unauthorized)) {
|
|
string? loginId = await _authService.GetLoginId();
|
|
|
|
if (!string.IsNullOrWhiteSpace(loginId) && authTokens is not null) {
|
|
AuthAttempt authAttempt = new() {
|
|
LoginID = loginId,
|
|
AuthTokens = authTokens
|
|
};
|
|
|
|
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "auth/refresh");
|
|
|
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authTokens.JwtToken);
|
|
|
|
request.Content = new StringContent(JsonSerializer.Serialize(authAttempt),
|
|
Encoding.UTF8,
|
|
"application/json");
|
|
|
|
HttpClient httpClient = new HttpClient() {
|
|
BaseAddress = new Uri(_apiBaseUrl)
|
|
};
|
|
|
|
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
|
|
|
|
HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request, cancellationToken);
|
|
|
|
if (httpResponseMessage.IsSuccessStatusCode) {
|
|
string responseContent = await httpResponseMessage.Content.ReadAsStringAsync();
|
|
|
|
JsonSerializerOptions jsonSerializerOptions = new() {
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
LoginResult loginResult = JsonSerializer.Deserialize<LoginResult>(responseContent, jsonSerializerOptions) ??
|
|
throw new Exception("Unable to parse login result from API response");
|
|
|
|
if (!loginResult.IsAuthenticated) throw new Exception($"User with Login ID {loginId} not authorized");
|
|
|
|
if (loginResult.AuthTokens is not null) {
|
|
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.AuthTokens.JwtToken);
|
|
await _authService.SetTokens(loginResult.AuthTokens.JwtToken, loginResult.AuthTokens.RefreshToken);
|
|
}
|
|
|
|
if (loginResult.User is not null)
|
|
await _authService.SetCurrentUser(loginResult.User);
|
|
} else {
|
|
await _authStateProvider.Logout();
|
|
|
|
string? redirectUrl = _cache.Get<string>("redirectUrl");
|
|
if (!string.IsNullOrWhiteSpace(redirectUrl)) {
|
|
_navigationManager.NavigateTo($"login/{redirectUrl}");
|
|
} else {
|
|
_navigationManager.NavigateTo("login");
|
|
}
|
|
}
|
|
}
|
|
|
|
return await base.SendAsync(requestMessage, cancellationToken);
|
|
}
|
|
|
|
return responseMessage;
|
|
}
|
|
}
|