namespace MxGateway.Server.Security.Authentication; public sealed class ApiKeyParser : IApiKeyParser { private const string BearerPrefix = "Bearer "; private const string TokenPrefix = "mxgw_"; public bool TryParseAuthorizationHeader(string? authorizationHeader, out ParsedApiKey? apiKey) { apiKey = null; if (string.IsNullOrWhiteSpace(authorizationHeader) || !authorizationHeader.StartsWith(BearerPrefix, StringComparison.OrdinalIgnoreCase)) { return false; } string token = authorizationHeader[BearerPrefix.Length..].Trim(); if (!token.StartsWith(TokenPrefix, StringComparison.OrdinalIgnoreCase)) { return false; } string keyPayload = token[TokenPrefix.Length..]; int separatorIndex = keyPayload.IndexOf('_', StringComparison.Ordinal); if (separatorIndex <= 0 || separatorIndex == keyPayload.Length - 1) { return false; } string keyId = keyPayload[..separatorIndex]; string secret = keyPayload[(separatorIndex + 1)..]; if (string.IsNullOrWhiteSpace(keyId) || string.IsNullOrWhiteSpace(secret)) { return false; } apiKey = new ParsedApiKey(keyId, secret); return true; } }