Skip to content

Commit 4046c10

Browse files
committed
support api_key as part of the url
1 parent 2e5dba2 commit 4046c10

File tree

5 files changed

+83
-22
lines changed

5 files changed

+83
-22
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using DigmaSSEServer.Options;
2+
using Microsoft.Extensions.Options;
3+
4+
namespace DigmaSSEServer.Authentication;
5+
6+
public class ApiKeyValidatorMiddleware
7+
{
8+
private readonly RequestDelegate _next;
9+
private readonly string _token;
10+
const string INVALID_API_KEY = "unauthorized access invalid api key";
11+
12+
public ApiKeyValidatorMiddleware(RequestDelegate rd, IOptions<AuthOptions> options)
13+
{
14+
_next = rd;
15+
_token = options.Value.Token;
16+
}
17+
private async Task UnauthorizedAccess(HttpContext httpContext, string errorMessage)
18+
{
19+
httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
20+
await httpContext.Response.WriteAsync(errorMessage);
21+
}
22+
23+
public async Task Invoke(HttpContext httpContext)
24+
{
25+
var routeValue = httpContext.GetRouteValue(Constants.API_KEY_NAME);
26+
if (routeValue == null) await UnauthorizedAccess(httpContext,INVALID_API_KEY);
27+
var apiKey = (string)routeValue!;
28+
if (apiKey != _token)
29+
{
30+
await UnauthorizedAccess(httpContext,INVALID_API_KEY);
31+
return;
32+
}
33+
34+
35+
await _next.Invoke(httpContext);
36+
}
37+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace DigmaSSEServer.Authentication;
2+
3+
public class Constants
4+
{
5+
public const string API_KEY_NAME = "api_key";
6+
public const string RoutePatternPrefix = $"/mcp/{{{API_KEY_NAME}}}";
7+
}

src/DigmaSSEServer/DigmaConfigurator.cs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,10 @@ static HttpClientHandler CreateHandler()
2626
return handler;
2727
}
2828

29-
services.AddHttpClient(TokenClientName, (sp, c) =>
30-
{
31-
var digma = sp.GetRequiredService<IOptions<DigmaOptions>>().Value;
32-
var auth = sp.GetRequiredService<IOptions<AuthOptions>>().Value;
33-
34-
c.BaseAddress = new Uri(digma.AnalyticsApi);
35-
c.DefaultRequestHeaders.Add("Digma-Access-Token", auth.Token);
36-
})
29+
services.AddHttpClient(TokenClientName, ConfigureHttpClient)
3730
.ConfigurePrimaryHttpMessageHandler(CreateHandler);
3831

39-
services.AddHttpClient<DigmaClient>((sp, c) =>
40-
{
41-
var digma = sp.GetRequiredService<IOptions<DigmaOptions>>().Value;
42-
var auth = sp.GetRequiredService<IOptions<AuthOptions>>().Value;
43-
44-
c.BaseAddress = new Uri(digma.AnalyticsApi);
45-
c.DefaultRequestHeaders.Add("Digma-Access-Token", auth.Token);
46-
})
32+
services.AddHttpClient<DigmaClient>(ConfigureHttpClient)
4733
.ConfigurePrimaryHttpMessageHandler(sp =>
4834
{
4935
var delegating = sp.GetRequiredService<BearerTokenHandler>();
@@ -61,4 +47,13 @@ static HttpClientHandler CreateHandler()
6147

6248
return services;
6349
}
50+
51+
private static void ConfigureHttpClient(IServiceProvider sp, HttpClient c)
52+
{
53+
var digma = sp.GetRequiredService<IOptions<DigmaOptions>>().Value;
54+
var auth = sp.GetRequiredService<IOptions<AuthOptions>>().Value;
55+
56+
c.BaseAddress = new Uri(digma.AnalyticsApi);
57+
c.DefaultRequestHeaders.Add("Digma-Access-Token", $"Token {auth.Token}");
58+
}
6459
}

src/DigmaSSEServer/Program.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,38 @@
1-
using System.Net;
21
using DigmaSSEServer;
2+
using DigmaSSEServer.Authentication;
3+
using DigmaSSEServer.Options;
34
using DigmaSSEServer.Tools;
5+
using Microsoft.Extensions.Options;
46
using ModelContextProtocol.Protocol.Types;
57

68
var builder = WebApplication.CreateBuilder(args);
79

810
builder.Services.AddDigma(builder.Configuration);
9-
1011
builder.Services
11-
.AddMcpServer(options => options.ServerInfo = new Implementation()
12+
.AddMcpServer(options =>
1213
{
13-
Name = "Digma Server",
14-
Version = "1.0"
14+
options.ServerInfo = new Implementation()
15+
{
16+
Name = "Digma Server",
17+
Version = "1.0"
18+
19+
};
1520
})
1621
.WithHttpTransport() // OR WithStdioServerTransport()
1722
.WithTools<CodeObservabilityTool>();
1823

1924
var app = builder.Build();
25+
var authOptions = app.Services.GetRequiredService<IOptions<AuthOptions>>();
26+
if (string.IsNullOrWhiteSpace(authOptions.Value.Token))
27+
{
28+
Console.WriteLine("ERROR: Missing required configuration 'Auth__Token must be specified'");
29+
Environment.Exit(1); // Exit with failure code
30+
return;
31+
}
32+
33+
app.MapMcp(Constants.RoutePatternPrefix);
34+
2035

21-
app.MapMcp();
36+
app.UseMiddleware<ApiKeyValidatorMiddleware>();
2237

2338
app.Run();

src/DigmaSSEServer/appsettings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
"Microsoft.AspNetCore": "Warning"
66
}
77
},
8+
"Kestrel": {
9+
"Endpoints": {
10+
"Http": {
11+
"Url": "http://0.0.0.0:3000"
12+
}
13+
}
14+
},
815
"AllowedHosts": "*",
916
"Digma": {
1017
"AnalyticsApi": ""

0 commit comments

Comments
 (0)