53 lines
1.7 KiB
C#
53 lines
1.7 KiB
C#
using System.Net;
|
|
using Microsoft.Extensions.Primitives;
|
|
|
|
namespace Alchegos.MCP.Filters;
|
|
|
|
public class McpAuthFilter : IEndpointFilter
|
|
{
|
|
private readonly ILogger<McpAuthFilter> _logger;
|
|
|
|
public McpAuthFilter(ILogger<McpAuthFilter> logger)
|
|
{
|
|
_logger = logger;
|
|
}
|
|
|
|
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
|
|
{
|
|
var expectedToken = Environment.GetEnvironmentVariable("MCP_API_KEY");
|
|
|
|
if (string.IsNullOrEmpty(expectedToken))
|
|
{
|
|
_logger.LogCritical("Required environment variable 'MCP_API_KEY' is not set.");
|
|
return Results.StatusCode((int)HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
var httpContext = context.HttpContext;
|
|
|
|
if (!httpContext.Request.Headers.TryGetValue("X-Api-Key", out StringValues receivedTokenValues) || receivedTokenValues.Count == 0)
|
|
{
|
|
_logger.LogWarning("MCP request rejected: Missing 'X-Api-Key' header.");
|
|
return Results.Unauthorized();
|
|
}
|
|
|
|
var receivedToken = receivedTokenValues.ToString();
|
|
if (!SecureCompare(receivedToken, expectedToken))
|
|
{
|
|
_logger.LogWarning("MCP request rejected: Invalid API Key provided.");
|
|
return Results.Unauthorized();
|
|
}
|
|
|
|
_logger.LogInformation("MCP request authenticated successfully.");
|
|
return await next(context);
|
|
}
|
|
|
|
private static bool SecureCompare(string a, string b)
|
|
{
|
|
a ??= string.Empty;
|
|
b ??= string.Empty;
|
|
if (a.Length != b.Length) return false;
|
|
int diff = 0;
|
|
for (int i = 0; i < a.Length; i++) diff |= a[i] ^ b[i];
|
|
return diff == 0;
|
|
}
|
|
} |