Implement RFC 9207 issuer validation in ClientOAuthProvider (#1605)
This commit is contained in:
parent
990bd76b53
commit
4aade88558
1 changed files with 707 additions and 149 deletions
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using ModelContextProtocol.Authentication;
|
||||
using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using System.Diagnostics;
|
||||
|
|
@ -32,7 +33,7 @@ var transport = new HttpClientTransport(new()
|
|||
OAuth = new()
|
||||
{
|
||||
RedirectUri = new Uri("http://localhost:1179/callback"),
|
||||
AuthorizationRedirectDelegate = HandleAuthorizationUrlAsync,
|
||||
AuthorizationCallbackHandler = HandleAuthorizationUrlAsync,
|
||||
DynamicClientRegistration = new()
|
||||
{
|
||||
ClientName = "ProtectedMcpClient",
|
||||
|
|
@ -68,12 +69,16 @@ if (tools.Any(t => t.Name == "get_alerts"))
|
|||
/// Handles the OAuth authorization URL by starting a local HTTP server and opening a browser.
|
||||
/// This implementation demonstrates how SDK consumers can provide their own authorization flow.
|
||||
/// </summary>
|
||||
/// <param name="authorizationUrl">The authorization URL to open in the browser.</param>
|
||||
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
|
||||
/// <param name="authorizationContext">The context containing the authorization and redirect URIs.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The authorization code extracted from the callback, or null if the operation failed.</returns>
|
||||
static async Task<string?> HandleAuthorizationUrlAsync(Uri authorizationUrl, Uri redirectUri, CancellationToken cancellationToken)
|
||||
/// <returns>The authorization result extracted from the callback, or null if the operation failed.</returns>
|
||||
static async Task<AuthorizationResult?> HandleAuthorizationUrlAsync(
|
||||
AuthorizationCallbackContext authorizationContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var authorizationUrl = authorizationContext.AuthorizationUri;
|
||||
var redirectUri = authorizationContext.RedirectUri;
|
||||
|
||||
Console.WriteLine("Starting OAuth authorization flow...");
|
||||
Console.WriteLine($"Opening browser to: {authorizationUrl}");
|
||||
|
||||
|
|
@ -93,6 +98,7 @@ static async Task<string?> HandleAuthorizationUrlAsync(Uri authorizationUrl, Uri
|
|||
var context = await listener.GetContextAsync();
|
||||
var query = HttpUtility.ParseQueryString(context.Request.Url?.Query ?? string.Empty);
|
||||
var code = query["code"];
|
||||
var iss = query["iss"];
|
||||
var error = query["error"];
|
||||
|
||||
string responseHtml = "<html><body><h1>Authentication complete</h1><p>You can close this window now.</p></body></html>";
|
||||
|
|
@ -115,7 +121,7 @@ static async Task<string?> HandleAuthorizationUrlAsync(Uri authorizationUrl, Uri
|
|||
}
|
||||
|
||||
Console.WriteLine("Authorization code received successfully.");
|
||||
return code;
|
||||
return new AuthorizationResult { Code = code, Iss = iss };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue