Skip to content

Commit 01f0e89

Browse files
committed
Minor tweaks to update logic for PRM
1 parent 5d32edd commit 01f0e89

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

src/ModelContextProtocol.AspNetCore/Authentication/McpAuthenticationHandler.cs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@ public McpAuthenticationHandler(
2727
: base(options, logger, encoder)
2828
{
2929
_optionsMonitor = options;
30-
_resourceMetadataPath = options.CurrentValue.ResourceMetadataUri.ToString();
30+
31+
// Note: this.Options is not fully available here.
32+
// _resourceMetadataPath will be correctly updated by GetAbsoluteResourceMetadataUri
33+
// or can be fetched from this.Options directly in HandleRequestAsync if needed.
34+
// For initial setup, if ResourceMetadataUri can be different per scheme,
35+
// this might need to be deferred or handled carefully.
36+
// However, GetAbsoluteResourceMetadataUri which is called by HandleChallengeAsync
37+
// will use this.Options and update _resourceMetadataPath.
38+
// And HandleResourceMetadataRequestAsync will also use this.Options.
39+
_resourceMetadataPath = options.CurrentValue.ResourceMetadataUri?.ToString() ?? string.Empty;
3140
}
3241

3342
/// <inheritdoc />
@@ -36,13 +45,19 @@ public async Task<bool> HandleRequestAsync()
3645
// Check if the request is for the resource metadata endpoint
3746
string requestPath = Request.Path.Value ?? string.Empty;
3847

48+
string expectedMetadataPath = this.Options.ResourceMetadataUri?.ToString() ?? string.Empty;
49+
if (this.Options.ResourceMetadataUri != null && !this.Options.ResourceMetadataUri.IsAbsoluteUri)
50+
{
51+
// For relative URIs, it's just the path component.
52+
expectedMetadataPath = this.Options.ResourceMetadataUri.OriginalString;
53+
}
54+
3955
// If the path doesn't match, let the request continue through the pipeline
40-
if (!string.Equals(requestPath, _resourceMetadataPath, StringComparison.OrdinalIgnoreCase))
56+
if (!string.Equals(requestPath, expectedMetadataPath, StringComparison.OrdinalIgnoreCase))
4157
{
4258
return false;
4359
}
4460

45-
// Use the request's cancellation token if available
4661
var cancellationToken = Request.HttpContext.RequestAborted;
4762
await HandleResourceMetadataRequestAsync(cancellationToken);
4863
return true;
@@ -58,27 +73,28 @@ public async Task<bool> HandleRequestAsync()
5873
/// </summary>
5974
private string GetAbsoluteResourceMetadataUri()
6075
{
61-
var options = _optionsMonitor.CurrentValue;
76+
var options = this.Options;
6277
var resourceMetadataUri = options.ResourceMetadataUri;
6378

6479
// If the options have changed, update the cached path
65-
string currentPath = resourceMetadataUri.ToString();
66-
if (_resourceMetadataPath != currentPath)
80+
string currentPath = resourceMetadataUri?.ToString() ?? string.Empty;
81+
if (_resourceMetadataPath != currentPath && resourceMetadataUri != null)
6782
{
68-
_resourceMetadataPath = currentPath;
83+
_resourceMetadataPath = resourceMetadataUri.IsAbsoluteUri ? currentPath : resourceMetadataUri.OriginalString;
6984
}
7085

71-
if (resourceMetadataUri.IsAbsoluteUri)
86+
if (resourceMetadataUri != null && resourceMetadataUri.IsAbsoluteUri)
7287
{
7388
return currentPath;
7489
}
7590

7691
// For relative URIs, combine with the base URL
7792
string baseUrl = GetBaseUrl();
78-
79-
if (!Uri.TryCreate(baseUrl + _resourceMetadataPath, UriKind.Absolute, out var absoluteUri))
93+
string relativePath = resourceMetadataUri?.OriginalString.TrimStart('/') ?? string.Empty;
94+
95+
if (!Uri.TryCreate($"{baseUrl.TrimEnd('/')}/{relativePath}", UriKind.Absolute, out var absoluteUri))
8096
{
81-
throw new InvalidOperationException("Could not create absolute URI for resource metadata.");
97+
throw new InvalidOperationException($"Could not create absolute URI for resource metadata. Base URL: {baseUrl}, Relative Path: {relativePath}");
8298
}
8399

84100
return absoluteUri.ToString();
@@ -90,8 +106,7 @@ private string GetAbsoluteResourceMetadataUri()
90106
/// <param name="cancellationToken">A token to cancel the operation.</param>
91107
private Task HandleResourceMetadataRequestAsync(CancellationToken cancellationToken = default)
92108
{
93-
// Get resource metadata from options, using the dynamic provider if available
94-
var options = _optionsMonitor.CurrentValue;
109+
var options = this.Options;
95110
var resourceMetadata = options.GetResourceMetadata(Request.HttpContext);
96111

97112
// Create a copy to avoid modifying the original
@@ -136,7 +151,6 @@ protected override Task HandleChallengeAsync(AuthenticationProperties properties
136151
// Get the absolute URI for the resource metadata
137152
string rawPrmDocumentUri = GetAbsoluteResourceMetadataUri();
138153

139-
// Initialize properties if null
140154
properties ??= new AuthenticationProperties();
141155

142156
// Store the resource_metadata in properties in case other handlers need it

src/ModelContextProtocol.AspNetCore/Authentication/McpAuthenticationOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,6 @@ internal ProtectedResourceMetadata GetResourceMetadata(HttpContext context)
101101
return provider != null
102102
? provider(context)
103103
: _resourceMetadata ?? throw new InvalidOperationException(
104-
"ResourceMetadata has not been configured. Use ResourceMetadata property setter or UseStaticResourceMetadata method to provide a valid resource URI.");
104+
"ResourceMetadata has not been configured.");
105105
}
106106
}

0 commit comments

Comments
 (0)