Skip to content

Commit b9ba2b9

Browse files
committed
Update Program.cs
1 parent 8c790db commit b9ba2b9

File tree

1 file changed

+59
-21
lines changed

1 file changed

+59
-21
lines changed

samples/SecureWeatherServer/Program.cs

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
using Microsoft.AspNetCore.Authentication;
2+
using Microsoft.Extensions.Options;
13
using ModelContextProtocol.AspNetCore;
24
using ModelContextProtocol.Protocol.Types;
3-
using Microsoft.AspNetCore.Authentication.JwtBearer;
5+
using System.Security.Claims;
6+
using System.Text.Encodings.Web;
47

58
var builder = WebApplication.CreateBuilder(args);
69

@@ -68,33 +71,17 @@
6871
// Configure the OAuth metadata for this server
6972
metadata.AuthorizationServers.Add(new Uri("https://auth.example.com"));
7073

74+
7175
// Define the scopes this server supports
7276
metadata.ScopesSupported.AddRange(["weather.read", "weather.write"]);
7377

7478
// Add optional documentation
7579
metadata.ResourceDocumentation = new Uri("https://docs.example.com/api/weather");
7680
});
7781

78-
// Configure authentication
79-
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
80-
.AddJwtBearer(options =>
81-
{
82-
// In a real app, you would configure proper JWT validation
83-
options.Events = new JwtBearerEvents
84-
{
85-
OnMessageReceived = context =>
86-
{
87-
// Simple demo authentication - in a real app, use proper JWT validation
88-
var token = context.Request.Headers.Authorization.ToString().Replace("Bearer ", "");
89-
if (token == "valid_token")
90-
{
91-
// For demo purposes, simulate successful auth with a valid token
92-
context.Success();
93-
}
94-
return Task.CompletedTask;
95-
}
96-
};
97-
});
82+
// Configure authentication using the built-in authentication system
83+
builder.Services.AddAuthentication("Bearer")
84+
.AddScheme<AuthenticationSchemeOptions, SimpleAuthHandler>("Bearer", options => { });
9885

9986
// Add authorization policy for MCP
10087
builder.Services.AddAuthorization(options =>
@@ -130,3 +117,54 @@
130117
Console.WriteLine("Press Ctrl+C to stop the server");
131118

132119
await app.RunAsync();
120+
121+
// Simple auth handler that validates a test token
122+
// In a real app, you'd use a JWT handler or other proper authentication
123+
class SimpleAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
124+
{
125+
public SimpleAuthHandler(
126+
IOptionsMonitor<AuthenticationSchemeOptions> options,
127+
ILoggerFactory logger,
128+
UrlEncoder encoder)
129+
: base(options, logger, encoder)
130+
{
131+
}
132+
133+
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
134+
{
135+
// Get the Authorization header
136+
if (!Request.Headers.TryGetValue("Authorization", out var authHeader))
137+
{
138+
return Task.FromResult(AuthenticateResult.Fail("Authorization header missing"));
139+
}
140+
141+
// Parse the token
142+
var headerValue = authHeader.ToString();
143+
if (!headerValue.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
144+
{
145+
return Task.FromResult(AuthenticateResult.Fail("Bearer token missing"));
146+
}
147+
148+
var token = headerValue["Bearer ".Length..].Trim();
149+
150+
// Validate the token - in a real app, this would validate a JWT
151+
if (token != "valid_token")
152+
{
153+
return Task.FromResult(AuthenticateResult.Fail("Invalid token"));
154+
}
155+
156+
// Create a claims identity with required claims
157+
var claims = new[]
158+
{
159+
new Claim(ClaimTypes.Name, "demo_user"),
160+
new Claim(ClaimTypes.NameIdentifier, "user123"),
161+
new Claim("scope", "weather.read")
162+
};
163+
164+
var identity = new ClaimsIdentity(claims, "Bearer");
165+
var principal = new ClaimsPrincipal(identity);
166+
var ticket = new AuthenticationTicket(principal, "Bearer");
167+
168+
return Task.FromResult(AuthenticateResult.Success(ticket));
169+
}
170+
}

0 commit comments

Comments
 (0)