|
1 | 1 | using Microsoft.AspNetCore.Authentication; |
2 | 2 | using Microsoft.Extensions.Options; |
| 3 | +using ModelContextProtocol.AspNetCore.Auth; |
3 | 4 | using ModelContextProtocol.Protocol.Types; |
4 | 5 | using System.Security.Claims; |
5 | 6 | using System.Text.Encodings.Web; |
6 | 7 |
|
7 | 8 | var builder = WebApplication.CreateBuilder(args); |
8 | 9 |
|
| 10 | +// Configure authentication to use MCP for challenges |
| 11 | +builder.Services.AddAuthentication(options => |
| 12 | +{ |
| 13 | + options.DefaultScheme = "Bearer"; |
| 14 | + options.DefaultChallengeScheme = McpAuthenticationDefaults.AuthenticationScheme; // Use MCP for challenges |
| 15 | +}) |
| 16 | +.AddScheme<AuthenticationSchemeOptions, SimpleAuthHandler>("Bearer", options => { }) |
| 17 | +.AddMcp(options => { |
| 18 | + // Configure MCP authentication options with the resource metadata URI |
| 19 | + options.ResourceMetadataUri = new Uri("/.well-known/oauth-protected-resource", UriKind.Relative); |
| 20 | + |
| 21 | + // Configure the resource metadata using our enhanced options |
| 22 | + options.ResourceMetadata.Resource = new Uri("http://localhost:7071"); |
| 23 | + options.ResourceMetadata.AuthorizationServers.Add(new Uri("https://login.microsoftonline.com/a2213e1c-e51e-4304-9a0d-effe57f31655/v2.0")); |
| 24 | + options.ResourceMetadata.BearerMethodsSupported.Add("header"); |
| 25 | + options.ResourceMetadata.ScopesSupported.AddRange(["weather.read", "weather.write"]); |
| 26 | + options.ResourceMetadata.ResourceDocumentation = new Uri("https://docs.example.com/api/weather"); |
| 27 | +}); |
| 28 | + |
| 29 | +// Add authorization services |
| 30 | +builder.Services.AddAuthorization(options => |
| 31 | +{ |
| 32 | + options.AddPolicy(McpAuthenticationDefaults.AuthenticationScheme, policy => |
| 33 | + { |
| 34 | + policy.RequireAuthenticatedUser(); |
| 35 | + }); |
| 36 | +}); |
| 37 | + |
| 38 | +// Don't forget to register the ResourceMetadataService |
| 39 | +builder.Services.AddSingleton<ResourceMetadataService>(); |
| 40 | + |
| 41 | +// IMPORTANT: Register the McpAuthorizationMarker to enable authorization on MCP endpoints |
| 42 | +builder.Services.AddSingleton<McpAuthorizationMarker>(); |
| 43 | + |
9 | 44 | // Configure MCP Server |
10 | 45 | builder.Services.AddMcpServer(options => |
11 | 46 | { |
|
64 | 99 | } |
65 | 100 | }; |
66 | 101 | }) |
67 | | -.WithHttpTransport() |
68 | | -.WithAuthorization(metadata => |
69 | | -{ |
70 | | - metadata.AuthorizationServers.Add(new Uri("https://login.microsoftonline.com/a2213e1c-e51e-4304-9a0d-effe57f31655/v2.0")); |
71 | | - metadata.BearerMethodsSupported.Add("header"); |
72 | | - metadata.ScopesSupported.AddRange(["weather.read", "weather.write"]); |
73 | | - |
74 | | - // Add optional documentation |
75 | | - metadata.ResourceDocumentation = new Uri("https://docs.example.com/api/weather"); |
76 | | -}); |
| 102 | +.WithHttpTransport(); |
77 | 103 |
|
78 | 104 | var app = builder.Build(); |
79 | 105 |
|
@@ -151,8 +177,6 @@ protected override Task<AuthenticateResult> HandleAuthenticateAsync() |
151 | 177 | return Task.FromResult(AuthenticateResult.Success(ticket)); |
152 | 178 | } |
153 | 179 |
|
154 | | - protected override Task HandleChallengeAsync(AuthenticationProperties properties) |
155 | | - { |
156 | | - return base.HandleChallengeAsync(properties); |
157 | | - } |
| 180 | + // The MCP authentication handler will handle challenges |
| 181 | + // so we don't need to implement HandleChallengeAsync here |
158 | 182 | } |
0 commit comments