Implemented with Antigravity.

This commit is contained in:
Creeper Lv
2026-06-01 05:09:20 +10:00
parent aaad155a30
commit e8ab8e0684
38 changed files with 3908 additions and 47 deletions
+99
View File
@@ -0,0 +1,99 @@
using System;
using System.Security.Claims;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
using SNote.Server.Security;
namespace SNote.Server.Security;
public static class AuthHelper
{
public static string? GetAuthenticatedUser(HttpContext context, CertificateManager certificateManager)
{
var token = GetBearerToken(context);
if (string.IsNullOrEmpty(token)) return null;
try
{
var principal = ValidateToken(token, certificateManager);
// Verify it has a Name claim and is not just a server token
var isServer = principal.HasClaim(c => c.Type == "IsServer" && c.Value == "true");
if (isServer) return null;
return principal.Identity?.Name;
}
catch
{
return null;
}
}
public static bool IsServerAuthenticated(HttpContext context, CertificateManager certificateManager)
{
var token = GetBearerToken(context);
if (string.IsNullOrEmpty(token)) return false;
try
{
var principal = ValidateToken(token, certificateManager);
return principal.HasClaim(c => c.Type == "IsServer" && c.Value == "true");
}
catch
{
return false;
}
}
// Helper to generate a server token for outgoing sync requests
public static string GenerateServerToken(CertificateManager certificateManager)
{
var cert = certificateManager.GetCertificate();
var privateKey = new X509SecurityKey(cert);
var claims = new[]
{
new Claim(ClaimTypes.Name, "SNoteServerNetwork"),
new Claim("IsServer", "true")
};
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddMinutes(15), // Short-lived for security
SigningCredentials = new SigningCredentials(privateKey, SecurityAlgorithms.RsaSha256)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
private static string? GetBearerToken(HttpContext context)
{
var authHeader = context.Request.Headers["Authorization"].ToString();
if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
{
return null;
}
return authHeader.Substring("Bearer ".Length).Trim();
}
private static ClaimsPrincipal ValidateToken(string token, CertificateManager certificateManager)
{
var cert = certificateManager.GetCertificate();
var publicKey = new X509SecurityKey(cert);
var validationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = publicKey,
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.FromMinutes(5)
};
var handler = new JwtSecurityTokenHandler();
return handler.ValidateToken(token, validationParameters, out _);
}
}