using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NetworkResurrector.Application.Services; using NetworkResurrector.Domain.Entities; using System; using System.Linq; using System.Net.Http.Headers; using System.Security.Claims; using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; namespace NetworkResurrector.Api.Authentication { public class BasicAuthenticationHandler : AuthenticationHandler { private readonly IUserService _userService; public BasicAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUserService userService) : base(options, logger, encoder, clock) { _userService = userService; } protected override async Task HandleAuthenticateAsync() { if (!Request.Headers.ContainsKey("Authorization")) return AuthenticateResult.Fail("Missing Authorization Header"); User user; try { var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); var credentialBytes = Convert.FromBase64String(authHeader.Parameter); var credentials = Encoding.UTF8.GetString(credentialBytes).Split(':'); var username = credentials.First(); var password = credentials.Last(); user = await _userService.Authenticate(username, password); } catch { return AuthenticateResult.Fail("Invalid Authorization Header"); } if (user == null) return AuthenticateResult.Fail("Invalid Username or Password"); var claims = new[] { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.UserName), }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return AuthenticateResult.Success(ticket); } } }