feat(core): add jwt validation to Authorization middleware

This commit is contained in:
2026-06-17 11:58:22 +02:00
parent 8addf1ceeb
commit 0a64890474
4 changed files with 80 additions and 6 deletions
+64 -5
View File
@@ -1,17 +1,23 @@
using System.Security.Cryptography;
using Core.Models;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
namespace Core.Middlewares;
public class AuthorizationMiddleware(RequestDelegate next)
public class AuthorizationMiddleware(RequestDelegate next, IServiceProvider serviceProvider)
{
public Task Invoke(HttpContext httpContext, CookiePlayerData playerData)
public async Task Invoke(HttpContext httpContext, CookiePlayerData playerData)
{
var cookieHeader = httpContext.Request.Headers.Cookie.ToString();
if (cookieHeader.Trim() == "")
{
httpContext.Response.StatusCode = 401;
return Task.CompletedTask;
await Task.CompletedTask;
return;
}
var hasSid = httpContext.Request.Cookies.ContainsKey("sid");
@@ -21,13 +27,66 @@ public class AuthorizationMiddleware(RequestDelegate next)
if (!(hasSid && hasUser && hasVersion))
{
httpContext.Response.StatusCode = 401;
return Task.CompletedTask;
await Task.CompletedTask;
return;
}
var token = new JsonWebToken(httpContext.Request.Cookies["sid"]!.Split(":")[1]);
var memoryCache = serviceProvider.GetRequiredService<IMemoryCache>();
var validationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateLifetime = true,
ValidateActor = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "authentication",
IssuerSigningKeyResolver = (_, _, _, _) =>
{
return memoryCache.GetOrCreate("minecraftPublicKeys", entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1);
var minecraftPublicKeys = new HttpClient()
.GetFromJsonAsync<MinecraftPublicKeys>("https://api.minecraftservices.com/publickeys")
.GetAwaiter()
.GetResult();
var signingKeys = new List<SecurityKey>();
if (minecraftPublicKeys == null)
{
Console.WriteLine("Couldn't fetch Minecraft Public Keys");
return signingKeys;
}
var publicKeyBytes = Convert.FromBase64String(minecraftPublicKeys.AuthenticationKeys[0].PublicKey);
var rsa = RSA.Create();
rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out _);
signingKeys.Add(new RsaSecurityKey(rsa.ExportParameters(false)));
return signingKeys;
});
}
};
var validationResult = await new JsonWebTokenHandler().ValidateTokenAsync(token, validationParameters);
if (!validationResult.IsValid)
{
httpContext.Response.StatusCode = 401;
await Task.CompletedTask;
return;
}
playerData.Uuid = httpContext.Request.Cookies["sid"]!.Split(":")[2];
playerData.Name = httpContext.Request.Cookies["user"]!;
playerData.Version = httpContext.Request.Cookies["version"]!;
return next(httpContext);
await next(httpContext);
}
}