Foxchat.NET/Foxchat.Identity/Authorization/AuthenticationHandler.cs

50 lines
1.7 KiB
C#

using System.Security.Cryptography;
using System.Text.Encodings.Web;
using Foxchat.Core;
using Foxchat.Core.Utils;
using Foxchat.Identity.Database;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.BearerToken;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using NodaTime;
namespace Foxchat.Identity.Authorization;
public static class AuthenticationHandlerExtensions
{
public static void AddAuthenticationHandler(this IServiceCollection services)
{
}
}
public class FoxchatAuthenticationHandler(
IOptionsMonitor<BearerTokenOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
IdentityContext context,
IClock clock
) : AuthenticationHandler<AuthenticationSchemeOptions>(options, logger, encoder)
{
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
var header = Request.Headers.Authorization.ToString();
if (!header.StartsWith("bearer ", StringComparison.InvariantCultureIgnoreCase))
return AuthenticateResult.NoResult();
var token = header[7..];
if (!CryptoUtils.TryFromBase64String(token, out var rawToken))
return AuthenticateResult.Fail(new FoxchatError.BadRequest("Invalid token format"));
var hash = SHA512.HashData(rawToken);
var oauthToken = await context.Tokens
.Include(t => t.Account)
.Include(t => t.Application)
.FirstOrDefaultAsync(t => t.Hash == hash && t.Expires > clock.GetCurrentInstant());
if (oauthToken == null)
return AuthenticateResult.NoResult();
throw new NotImplementedException();
}
}