50 lines
No EOL
1.6 KiB
C#
50 lines
No EOL
1.6 KiB
C#
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<char> val = authorizationHeader.AsSpan(6); // basic + space
|
|
Span<byte> 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;
|
|
}
|
|
|
|
} |