using System.Net.Http.Headers; using System.Text; using System.Text.Encodings.Web; using Microsoft.Extensions.Options; namespace IOL.BookmarkThing.Server.Utilities; public class BasicAuthenticationHandler : AuthenticationHandler { private readonly AppDbContext _context; public BasicAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, AppDbContext context) : base(options, logger, encoder, clock) { _context = context; } protected override Task HandleAuthenticateAsync() { var endpoint = Context.GetEndpoint(); if (endpoint?.Metadata.GetMetadata() != null) return Task.FromResult(AuthenticateResult.NoResult()); if (!Request.Headers.ContainsKey("Authorization")) return Task.FromResult(AuthenticateResult.Fail("Missing Authorization Header")); try { var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); if (authHeader.Parameter == null) return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); var credentialBytes = Convert.FromBase64String(authHeader.Parameter); var token_is_guid = Guid.TryParse(Encoding.UTF8.GetString(credentialBytes), out var token_id); if (token_is_guid) { var token = _context.AccessTokens.Include(c => c.User).SingleOrDefault(c => c.Id == token_id); if (token == default) { return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); } var claims = token.User.DefaultClaims(); var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return Task.FromResult(AuthenticateResult.Success(ticket)); } return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); } catch { return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); } } }