using System.Diagnostics.CodeAnalysis; using System.Text; using Microsoft.Extensions.Primitives; namespace IdentityShroud.Api.Helpers; public static class HeaderHelpers { public static bool TryGetBasicAuth( HttpContext context, [NotNullWhen(true)] out string? user, [NotNullWhen(true)] out string? password) { var headers = context?.Request.Headers; if (headers is not null) { if (headers.TryGetValue("Authorization", out StringValues s)) return TryDecodeBasicAuth(s.ToString(), out user, out password); } user = password = null; return false; } public static bool TryDecodeBasicAuth( string authorizationHeader, [NotNullWhen(true)] out string? user, [NotNullWhen(true)] out string? password) { if (authorizationHeader.StartsWith("basic ", StringComparison.OrdinalIgnoreCase)) { ReadOnlySpan val = authorizationHeader.AsSpan(6); // basic + space Span b = new byte[(val.Length * 6 / 8) + 1]; if (Convert.TryFromBase64Chars(val, b, out int written)) { int sepIdx = b.IndexOf((byte)':'); if (sepIdx > 0 && sepIdx < written - 1) { user = Encoding.UTF8.GetString(b.Slice(0, sepIdx)); password = Encoding.UTF8.GetString(b.Slice(sepIdx + 1, written - (sepIdx + 1))); return true; } } } user = password = null; return false; } }