Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,15 @@ internal partial class RemoteAppAuthenticationService : IRemoteAppAuthentication
private RemoteAppAuthenticationClientOptions? _options;

public RemoteAppAuthenticationService(
IHttpClientFactory httpClientFactory,
IAuthenticationResultFactory resultFactory,
IOptionsSnapshot<RemoteAppAuthenticationClientOptions> authOptions,
IOptions<RemoteAppClientOptions> remoteAppOptions,
ILogger<RemoteAppAuthenticationService> logger)
{
if (httpClientFactory is null)
{
throw new ArgumentNullException(nameof(httpClientFactory));
}

_resultFactory = resultFactory ?? throw new ArgumentNullException(nameof(resultFactory));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_authOptionsSnapshot = authOptions ?? throw new ArgumentNullException(nameof(authOptions));
_client = httpClientFactory.CreateClient(RemoteConstants.HttpClientName);
_client = remoteAppOptions?.Value.BackchannelClient ?? throw new ArgumentNullException(nameof(remoteAppOptions));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,11 @@ public static ISystemWebAdapterRemoteClientAppBuilder AddRemoteAppClient(this IS
throw new ArgumentNullException(nameof(configure));
}

builder.Services.AddSingleton<IPostConfigureOptions<RemoteAppClientOptions>, RemoteAppClientPostConfigureOptions>();
builder.Services.AddOptions<RemoteAppClientOptions>()
.Configure(configure)
.ValidateDataAnnotations();

builder.Services.AddHttpClient(RemoteConstants.HttpClientName)
.ConfigurePrimaryHttpMessageHandler(sp =>
{
var options = sp.GetRequiredService<IOptions<RemoteAppClientOptions>>().Value;

if (options.BackchannelHandler is { } handler)
{
return handler;
}

// Disable cookies in the HTTP client because the service will manage the cookie header directly
return new HttpClientHandler { UseCookies = false, AllowAutoRedirect = false };
})
.ConfigureHttpClient((sp, client) =>
{
var options = sp.GetRequiredService<IOptions<RemoteAppClientOptions>>().Value;

client.BaseAddress = options.RemoteAppUrl;
client.DefaultRequestHeaders.Add(options.ApiKeyHeader, options.ApiKey);
});

return new Builder(builder.Services);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ public Uri RemoteAppUrl
}

/// <summary>
/// Gets or sets an <see cref="HttpMessageHandler"/> to use for making requests to the remote app.
/// Gets or sets an <see cref="HttpMessageHandler"/> to use for making requests to the remote app. Used if BackchannelClient is null.
/// </summary>
public HttpMessageHandler? BackchannelHandler { get; set; }

/// <summary>
/// Gets or sets an <see cref="HttpClient"/> to use for making requests to the remote app.
/// </summary>
public HttpClient? BackchannelClient { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Net.Http;
using Microsoft.AspNetCore.SystemWebAdapters;
using Microsoft.Extensions.Options;

namespace Microsoft.Extensions.DependencyInjection;

internal class RemoteAppClientPostConfigureOptions : IPostConfigureOptions<RemoteAppClientOptions>
{
public void PostConfigure(string name, RemoteAppClientOptions options)
{
if (options.BackchannelClient is null)
{
options.BackchannelClient = new HttpClient(
options.BackchannelHandler
// Disable cookies in the HTTP client because the service will manage the cookie header directly
?? new HttpClientHandler { UseCookies = false, AllowAutoRedirect = false });

// Set base address and API key header based on options
if (options.RemoteAppUrl is not null)
{
options.BackchannelClient.BaseAddress = options.RemoteAppUrl;
}

if (!string.IsNullOrEmpty(options.ApiKeyHeader))
{
options.BackchannelClient.DefaultRequestHeaders.Add(options.ApiKeyHeader, options.ApiKey);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ namespace Microsoft.AspNetCore.SystemWebAdapters.SessionState.RemoteSession;

internal partial class RemoteAppSessionStateManager : ISessionManager
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ISessionSerializer _serializer;
private readonly ILogger<RemoteAppSessionStateManager> _logger;
private readonly RemoteAppSessionStateClientOptions _options;
private readonly HttpClient _backchannelClient;

public RemoteAppSessionStateManager(
IHttpClientFactory httpClientFactory,
ISessionSerializer serializer,
IOptions<RemoteAppSessionStateClientOptions> options,
IOptions<RemoteAppClientOptions> remoteAppClientOptions,
ILogger<RemoteAppSessionStateManager> logger)
{
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
_backchannelClient = remoteAppClientOptions?.Value.BackchannelClient ?? throw new ArgumentNullException(nameof(remoteAppClientOptions));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
_serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
}

Expand Down Expand Up @@ -79,8 +79,7 @@ private async Task<ISessionState> GetSessionDataAsync(string? sessionId, bool re
AddSessionCookieToHeader(req, sessionId);
AddReadOnlyHeader(req, readOnly);

using var client = _httpClientFactory.CreateClient(RemoteConstants.HttpClientName);
var response = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, token);
var response = await _backchannelClient.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, token);

LogRetrieveResponse(response.StatusCode);

Expand Down Expand Up @@ -120,8 +119,7 @@ private async Task SetOrReleaseSessionData(ISessionState? state, CancellationTok
req.Content = new SerializedSessionHttpContent(_serializer, state);
}

using var client = _httpClientFactory.CreateClient(RemoteConstants.HttpClientName);
using var response = await client.SendAsync(req, cancellationToken);
using var response = await _backchannelClient.SendAsync(req, cancellationToken);

LogCommitResponse(response.StatusCode);

Expand Down
2 changes: 0 additions & 2 deletions src/Services/RemoteConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@ namespace Microsoft.AspNetCore.SystemWebAdapters;
internal static class RemoteConstants
{
internal const string ApiKeyHeaderName = "X-SystemWebAdapter-RemoteAppAuthentication-Key";

internal const string HttpClientName = "remote-client";
}