Authorization Support (Using ASP.NET Core Native AuthN/AuthZ Integration) (#377)

This commit is contained in:
Den Delimarsky 🌺 2025-07-03 14:39:28 -07:00 • committed by GitHub
commit cdf88e7f5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Authentication;
using ModelContextProtocol.Protocol;
namespace ModelContextProtocol.Client;
@ -15,9 +16,10 @@ namespace ModelContextProtocol.Client;
public sealed class SseClientTransport : IClientTransport, IAsyncDisposable
{
private readonly SseClientTransportOptions _options;
private readonly HttpClient _httpClient;
private readonly McpHttpClient _mcpHttpClient;
private readonly ILoggerFactory? _loggerFactory;
private readonly bool _ownsHttpClient;
private readonly HttpClient? _ownedHttpClient;
/// <summary>
/// Initializes a new instance of the <see cref="SseClientTransport"/> class.
@ -45,10 +47,23 @@ public sealed class SseClientTransport : IClientTransport, IAsyncDisposable
Throw.IfNull(httpClient);
_options = transportOptions;
_httpClient = httpClient;
_loggerFactory = loggerFactory;
_ownsHttpClient = ownsHttpClient;
Name = transportOptions.Name ?? transportOptions.Endpoint.ToString();
if (transportOptions.OAuth is { } clientOAuthOptions)
{
var oAuthProvider = new ClientOAuthProvider(_options.Endpoint, clientOAuthOptions, httpClient, loggerFactory);
_mcpHttpClient = new AuthenticatingMcpHttpClient(httpClient, oAuthProvider);
}
else
{
_mcpHttpClient = new(httpClient);
}
if (ownsHttpClient)
{
_ownedHttpClient = httpClient;
}
}
/// <inheritdoc />
@ -59,8 +74,8 @@ public sealed class SseClientTransport : IClientTransport, IAsyncDisposable
{
return _options.TransportMode switch
{
HttpTransportMode.AutoDetect => new AutoDetectingClientSessionTransport(_options, _httpClient, _loggerFactory, Name),
HttpTransportMode.StreamableHttp => new StreamableHttpClientSessionTransport(Name, _options, _httpClient, messageChannel: null, _loggerFactory),
HttpTransportMode.AutoDetect => new AutoDetectingClientSessionTransport(Name, _options, _mcpHttpClient, _loggerFactory),
HttpTransportMode.StreamableHttp => new StreamableHttpClientSessionTransport(Name, _options, _mcpHttpClient, messageChannel: null, _loggerFactory),
HttpTransportMode.Sse => await ConnectSseTransportAsync(cancellationToken).ConfigureAwait(false),
_ => throw new InvalidOperationException($"Unsupported transport mode: {_options.TransportMode}"),
};
@ -68,7 +83,7 @@ public sealed class SseClientTransport : IClientTransport, IAsyncDisposable
private async Task<ITransport> ConnectSseTransportAsync(CancellationToken cancellationToken)
{
var sessionTransport = new SseClientSessionTransport(Name, _options, _httpClient, messageChannel: null, _loggerFactory);
var sessionTransport = new SseClientSessionTransport(Name, _options, _mcpHttpClient, messageChannel: null, _loggerFactory);
try
{
@ -85,11 +100,7 @@ public sealed class SseClientTransport : IClientTransport, IAsyncDisposable
/// <inheritdoc />
public ValueTask DisposeAsync()
{
if (_ownsHttpClient)
{
_httpClient.Dispose();
}
_ownedHttpClient?.Dispose();
return default;
}
}