OBSBoards/OBSBoardsWWW/JwtTokenMiddleware.cs
2024-11-03 17:32:03 +01:00

87 lines
3.4 KiB
C#

namespace OBSBoardsWWW
{
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
public class JwtTokenMiddleware
{
private readonly RequestDelegate _next;
private readonly IHttpClientFactory _httpClientFactory;
public JwtTokenMiddleware(RequestDelegate next, IHttpClientFactory httpClientFactory)
{
_next = next;
_httpClientFactory = httpClientFactory;
}
public async Task InvokeAsync(HttpContext context)
{
var token = context.Session.GetString("AccessToken");
var expirationString = context.Session.GetString("TokenExpiration");
if (!string.IsNullOrEmpty(token) && DateTime.TryParse(expirationString, out DateTime expiration))
{
// Sprawdź, czy token wygaśnie w ciągu następnych 1 minut
if (expiration < DateTime.UtcNow.AddMinutes(1))
{
// Wywołaj funkcję odświeżania tokena
token = await RefreshToken(context);
}
// Dodaj token do nagłówka Authorization
context.Request.Headers["Authorization"] = $"Bearer {token}";
}
await _next(context);
}
private async Task<string> RefreshToken(HttpContext context)
{
var accessToken = context.Session.GetString("AccessToken");
var refreshToken = context.Session.GetString("RefreshToken");
if (!string.IsNullOrEmpty(refreshToken))
{
var client = _httpClientFactory.CreateClient();
var content = new StringContent(JsonConvert.SerializeObject(new { Token = accessToken, RefreshToken = refreshToken }), Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://localhost:44372/api/Authenticate/RefreshToken", content);
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
var newTokenData = JsonConvert.DeserializeObject<TokenModel>(responseContent);
// Przechowaj nowy token i datę wygaśnięcia w sesji
context.Session.SetString("AccessToken", newTokenData.Token);
var jwtToken = new JwtSecurityTokenHandler().ReadToken(newTokenData.Token) as JwtSecurityToken;
var newExpiration = jwtToken.ValidTo;
context.Session.SetString("TokenExpiration", newExpiration.ToString());
return newTokenData.Token;
}
}
// Jeśli odświeżenie tokena się nie powiodło, wyloguj użytkownika
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
context.Session.Remove("AccessToken");
context.Session.Remove("RefreshToken");
context.Session.Remove("TokenExpiration");
context.Response.Redirect("/Auth/Login");
return null;
}
public class TokenModel
{
public string Token { get; set; }
public string RefreshToken { get; set; }
}
}
}