Skip to content

Commit 6b0b7ef

Browse files
committed
Cleanup
1 parent 1496b41 commit 6b0b7ef

2 files changed

Lines changed: 7 additions & 35 deletions

File tree

samples/ProtectedMCPClient/BasicOAuthAuthorizationProvider.cs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@ public class BasicOAuthAuthorizationProvider(
2626
{
2727
private readonly Uri _serverUrl = serverUrl ?? throw new ArgumentNullException(nameof(serverUrl));
2828
private readonly Uri _redirectUri = redirectUri ?? new Uri("http://localhost:8080/callback");
29-
private readonly List<string> _scopes = scopes?.ToList() ?? new List<string>();
30-
private readonly HttpClient _httpClient = new HttpClient();
29+
private readonly List<string> _scopes = scopes?.ToList() ?? [];
30+
private readonly HttpClient _httpClient = new();
3131

32-
// Single token storage
3332
private TokenContainer? _token;
3433

35-
// Store auth server metadata separately so token only stores token data
3634
private AuthorizationServerMetadata? _authServerMetadata;
3735

3836
public string AuthorizationScheme => "Bearer";
@@ -82,7 +80,7 @@ public async Task<bool> HandleUnauthorizedResponseAsync(HttpResponseMessage resp
8280
_authServerMetadata = authServerMetadata;
8381

8482
// Do the OAuth flow
85-
var token = await DoAuthorizationCodeFlowAsync(authServerMetadata, cancellationToken);
83+
var token = await InitiateAuthorizationCodeFlowAsync(authServerMetadata, cancellationToken);
8684
if (token != null)
8785
{
8886
_token = token;
@@ -102,11 +100,9 @@ public async Task<bool> HandleUnauthorizedResponseAsync(HttpResponseMessage resp
102100

103101
private async Task<AuthorizationServerMetadata?> GetAuthServerMetadataAsync(Uri authServerUri, CancellationToken cancellationToken)
104102
{
105-
// Ensure trailing slash
106103
var baseUrl = authServerUri.ToString();
107104
if (!baseUrl.EndsWith("/")) baseUrl += "/";
108105

109-
// Try both well-known endpoints
110106
foreach (var path in new[] { ".well-known/openid-configuration", ".well-known/oauth-authorization-server" })
111107
{
112108
try
@@ -145,8 +141,7 @@ public async Task<bool> HandleUnauthorizedResponseAsync(HttpResponseMessage resp
145141
{
146142
Content = requestContent
147143
};
148-
149-
// Add client auth if we have a secret
144+
150145
if (!string.IsNullOrEmpty(clientSecret))
151146
{
152147
var authValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}"));
@@ -162,7 +157,6 @@ public async Task<bool> HandleUnauthorizedResponseAsync(HttpResponseMessage resp
162157

163158
if (tokenResponse != null)
164159
{
165-
// Set obtained time and preserve refresh token if needed
166160
tokenResponse.ObtainedAt = DateTimeOffset.UtcNow;
167161
if (string.IsNullOrEmpty(tokenResponse.RefreshToken))
168162
{
@@ -181,22 +175,18 @@ public async Task<bool> HandleUnauthorizedResponseAsync(HttpResponseMessage resp
181175
return null;
182176
}
183177

184-
private async Task<TokenContainer?> DoAuthorizationCodeFlowAsync(
178+
private async Task<TokenContainer?> InitiateAuthorizationCodeFlowAsync(
185179
AuthorizationServerMetadata authServerMetadata,
186180
CancellationToken cancellationToken)
187181
{
188-
// Generate PKCE values
189182
var codeVerifier = GenerateCodeVerifier();
190183
var codeChallenge = GenerateCodeChallenge(codeVerifier);
191184

192-
// Build the auth URL
193185
var authUrl = BuildAuthorizationUrl(authServerMetadata, codeChallenge);
194186

195-
// Get auth code
196187
var authCode = await GetAuthorizationCodeAsync(authUrl, cancellationToken);
197188
if (string.IsNullOrEmpty(authCode)) return null;
198189

199-
// Exchange for token
200190
return await ExchangeCodeForTokenAsync(authServerMetadata, authCode, codeVerifier, cancellationToken);
201191
}
202192

@@ -231,18 +221,14 @@ private Uri BuildAuthorizationUrl(AuthorizationServerMetadata authServerMetadata
231221
{
232222
listener.Start();
233223

234-
// Open browser to the authorization URL
235224
OpenBrowser(authorizationUrl);
236225

237-
// Get the authorization code
238226
var context = await listener.GetContextAsync();
239227

240-
// Parse the response
241228
var query = HttpUtility.ParseQueryString(context.Request.Url?.Query ?? string.Empty);
242229
var code = query["code"];
243230
var error = query["error"];
244231

245-
// Send a response to the browser
246232
string responseHtml = "<html><body><h1>Authentication complete</h1><p>You can close this window now.</p></body></html>";
247233
byte[] buffer = Encoding.UTF8.GetBytes(responseHtml);
248234
context.Response.ContentLength64 = buffer.Length;
@@ -291,7 +277,6 @@ private Uri BuildAuthorizationUrl(AuthorizationServerMetadata authServerMetadata
291277
Content = requestContent
292278
};
293279

294-
// Add client auth if we have a secret
295280
if (!string.IsNullOrEmpty(clientSecret))
296281
{
297282
var authValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}"));
@@ -307,7 +292,6 @@ private Uri BuildAuthorizationUrl(AuthorizationServerMetadata authServerMetadata
307292

308293
if (tokenResponse != null)
309294
{
310-
// Set the time when the token was obtained
311295
tokenResponse.ObtainedAt = DateTimeOffset.UtcNow;
312296
return tokenResponse;
313297
}

samples/ProtectedMCPClient/Program.cs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using ModelContextProtocol.Authentication;
21
using ModelContextProtocol.Client;
32
using ModelContextProtocol.Protocol.Transport;
43

@@ -17,7 +16,7 @@ static async Task Main(string[] args)
1716
new Uri(serverUrl),
1817
clientId: "6ad97b5f-7a7b-413f-8603-7a3517d4adb8",
1918
redirectUri: new Uri("http://localhost:1179/callback"),
20-
scopes: new List<string> { "api://167b4284-3f92-4436-92ed-38b38f83ae08/weather.read" }
19+
scopes: ["api://167b4284-3f92-4436-92ed-38b38f83ae08/weather.read"]
2120
);
2221

2322
Console.WriteLine();
@@ -32,7 +31,6 @@ static async Task Main(string[] args)
3231
};
3332

3433
var transport = new SseClientTransport(transportOptions, tokenProvider);
35-
3634
var client = await McpClientFactory.CreateAsync(transport);
3735

3836
var tools = await client.ListToolsAsync();
@@ -58,24 +56,14 @@ static async Task Main(string[] args)
5856
Console.WriteLine();
5957
}
6058
}
61-
catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
62-
{
63-
// Handle authentication failures specifically
64-
Console.WriteLine("Authentication failed. The server returned a 401 Unauthorized response.");
65-
Console.WriteLine($"Details: {ex.Message}");
66-
67-
// Additional handling for 401 - could add manual authentication retry here
68-
Console.WriteLine("You might need to provide a different API key or authentication credentials.");
69-
}
7059
catch (Exception ex)
7160
{
7261
Console.WriteLine($"Error: {ex.Message}");
7362
if (ex.InnerException != null)
7463
{
7564
Console.WriteLine($"Inner error: {ex.InnerException.Message}");
7665
}
77-
78-
// Print stack trace in debug builds
66+
7967
#if DEBUG
8068
Console.WriteLine($"Stack trace: {ex.StackTrace}");
8169
#endif

0 commit comments

Comments
 (0)