93 lines
3.7 KiB
C#
93 lines
3.7 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}";
|
|
} else
|
|
{
|
|
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
|
context.Session.Remove("AccessToken");
|
|
context.Session.Remove("RefreshToken");
|
|
context.Session.Remove("TokenExpiration");
|
|
}
|
|
|
|
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; }
|
|
}
|
|
}
|
|
}
|