Skip to content

Commit 51bb38b

Browse files
committed
Cleanup for client logic
1 parent ceee919 commit 51bb38b

File tree

2 files changed

+6
-47
lines changed

2 files changed

+6
-47
lines changed

samples/ProtectedMCPClient/SimpleAccessTokenProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public async Task<bool> HandleUnauthorizedResponseAsync(HttpResponseMessage resp
3333
try
3434
{
3535
// Use the updated AuthenticationChallengeHandler to handle the 401 challenge
36-
var resourceMetadata = await AuthenticationUtils.HandleAuthenticationChallengeAsync(
36+
var resourceMetadata = await AuthenticationUtils.ExtractProtectedResourceMetadata(
3737
response,
3838
_serverUrl,
3939
cancellationToken);

src/ModelContextProtocol/Authentication/AuthenticationUtils.cs

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,13 @@ namespace ModelContextProtocol.Authentication;
99
/// </summary>
1010
public static class AuthenticationUtils
1111
{
12-
/// <summary>
13-
/// Extracts protected resource metadata from an unauthorized response.
14-
/// </summary>
15-
/// <param name="response">The HTTP response containing the WWW-Authenticate header.</param>
16-
/// <returns>The extracted ProtectedResourceMetadata, or null if it couldn't be extracted.</returns>
17-
public static ProtectedResourceMetadata? ExtractProtectedResourceMetadata(HttpResponseMessage response)
18-
{
19-
if (response.StatusCode != System.Net.HttpStatusCode.Unauthorized)
20-
{
21-
return null;
22-
}
23-
24-
// Extract the WWW-Authenticate header
25-
if (!response.Headers.WwwAuthenticate.Any())
26-
{
27-
return null;
28-
}
29-
30-
// Look for the Bearer authentication scheme with resource_metadata parameter
31-
foreach (var header in response.Headers.WwwAuthenticate)
32-
{
33-
if (header.Scheme.Equals("Bearer", StringComparison.OrdinalIgnoreCase))
34-
{
35-
var parameters = header.Parameter;
36-
if (string.IsNullOrEmpty(parameters))
37-
{
38-
continue;
39-
}
40-
41-
// Parse the parameters to find resource_metadata
42-
var resourceMetadataUrl = ParseWwwAuthenticateParameters(parameters, "resource_metadata");
43-
if (resourceMetadataUrl != null)
44-
{
45-
return FetchProtectedResourceMetadataAsync(new Uri(resourceMetadataUrl)).GetAwaiter().GetResult();
46-
}
47-
}
48-
}
49-
50-
return null;
51-
}
52-
5312
/// <summary>
5413
/// Fetches the protected resource metadata from the provided URL.
5514
/// </summary>
5615
/// <param name="metadataUrl">The URL to fetch the metadata from.</param>
5716
/// <param name="cancellationToken">A token to cancel the operation.</param>
5817
/// <returns>The fetched ProtectedResourceMetadata, or null if it couldn't be fetched.</returns>
59-
public static async Task<ProtectedResourceMetadata?> FetchProtectedResourceMetadataAsync(
18+
private static async Task<ProtectedResourceMetadata?> FetchProtectedResourceMetadataAsync(
6019
Uri metadataUrl,
6120
CancellationToken cancellationToken = default)
6221
{
@@ -145,7 +104,7 @@ public static class AuthenticationUtils
145104
/// <param name="protectedResourceMetadata">The metadata to verify.</param>
146105
/// <param name="serverUrl">The server URL to compare against.</param>
147106
/// <returns>True if the resource URI matches the server, otherwise false.</returns>
148-
public static bool VerifyResourceMatch(ProtectedResourceMetadata protectedResourceMetadata, Uri serverUrl)
107+
private static bool VerifyResourceMatch(ProtectedResourceMetadata protectedResourceMetadata, Uri serverUrl)
149108
{
150109
if (protectedResourceMetadata.Resource == null || serverUrl == null)
151110
{
@@ -171,7 +130,7 @@ public static bool VerifyResourceMatch(ProtectedResourceMetadata protectedResour
171130
/// <returns>The resource metadata if the resource matches the server, otherwise throws an exception.</returns>
172131
/// <exception cref="InvalidOperationException">Thrown when the response is not a 401, lacks a WWW-Authenticate header,
173132
/// lacks a resource_metadata parameter, the metadata can't be fetched, or the resource URI doesn't match the server URL.</exception>
174-
public static async Task<ProtectedResourceMetadata> HandleAuthenticationChallengeAsync(
133+
public static async Task<ProtectedResourceMetadata> ExtractProtectedResourceMetadata(
175134
HttpResponseMessage response,
176135
Uri serverUrl,
177136
CancellationToken cancellationToken = default)
@@ -238,14 +197,14 @@ public static async Task<ProtectedResourceMetadata> HandleAuthenticationChalleng
238197
/// <param name="parameters">The parameter string from the WWW-Authenticate header.</param>
239198
/// <param name="parameterName">The name of the parameter to extract.</param>
240199
/// <returns>The value of the parameter, or null if not found.</returns>
241-
public static string? ParseWwwAuthenticateParameters(string parameters, string parameterName)
200+
private static string? ParseWwwAuthenticateParameters(string parameters, string parameterName)
242201
{
243202
// Handle parameters in the format: param1="value1", param2="value2"
244203
var paramDict = parameters.Split(',')
245204
.Select(p => p.Trim())
246205
.Select(p =>
247206
{
248-
var parts = p.Split(new[] { '=' }, 2);
207+
var parts = p.Split(['='], 2);
249208
if (parts.Length != 2)
250209
{
251210
return new KeyValuePair<string, string>(string.Empty, string.Empty);

0 commit comments

Comments
 (0)