Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
10 changes: 4 additions & 6 deletions samples/MvcApp/Global.asax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ protected void Application_Start()

SystemWebAdapterConfiguration.AddSystemWebAdapters(this)
.AddProxySupport(options => options.UseForwardedHeaders = true)
.AddRemoteApp(options =>
{
options.ApiKey = ClassLibrary.RemoteServiceUtils.ApiKey;
})
.AddRemoteAppSession()
.AddJsonSessionSerializer(options => ClassLibrary.RemoteServiceUtils.RegisterSessionKeys(options.KnownKeys))
.AddRemoteAppAuthentication();
.AddRemoteAppServer(remote => remote
.Configure(options => options.ApiKey = ClassLibrary.RemoteServiceUtils.ApiKey)
.AddAuthentication()
.AddSession());
}
}
}
17 changes: 9 additions & 8 deletions samples/MvcCoreApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSystemWebAdapters()
.AddRemoteApp(options =>
{
options.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
options.ApiKey = ClassLibrary.RemoteServiceUtils.ApiKey;
})
.AddRemoteAppSession()
.AddJsonSessionSerializer(options => ClassLibrary.RemoteServiceUtils.RegisterSessionKeys(options.KnownKeys))
.AddRemoteAppAuthentication(true);
.AddRemoteAppClient(remote => remote
.Configure(options =>
{
options.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
options.ApiKey = ClassLibrary.RemoteServiceUtils.ApiKey;
})
.AddAuthentication(true)
.AddSession())
.AddJsonSessionSerializer(options => ClassLibrary.RemoteServiceUtils.RegisterSessionKeys(options.KnownKeys));

var app = builder.Build();

Expand Down
15 changes: 8 additions & 7 deletions samples/RemoteAuth/Bearer/RemoteBearer/Global.asax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ protected void Application_Start()
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

SystemWebAdapterConfiguration.AddSystemWebAdapters(this)
.AddRemoteApp(options =>
{
// A real application would not hard code this, but load it
// securely from environment or configuration
options.ApiKey = "TopSecretString";
})
.AddRemoteAppAuthentication();
.AddRemoteAppServer(remote => remote
.Configure(options =>
{
// A real application would not hard code this, but load it
// securely from environment or configuration
options.ApiKey = "TopSecretString";
})
.AddAuthentication());
}
}
}
28 changes: 15 additions & 13 deletions samples/RemoteAuth/Bearer/RemoteBearerCore/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
builder.Services.AddControllers();

builder.Services.AddSystemWebAdapters()
.AddRemoteApp(options =>
{
options.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);

// A real application would not hard code this, but load it
// securely from environment or configuration
options.ApiKey = "TopSecretString";
})
// This registers the remote app authentication handler. The boolean argument indicates whether remote app auth
// should be the default scheme. If it is set to false, HTTP requests to authenticate will only be made for
// endpoints that actually need that behavior, but it is then necessary to annotate endpoints requiring remote app
// auth with [Authorize(AuthenticationSchemes = RemoteAppAuthenticationDefaults.AuthenticationScheme)] or something similar.
.AddRemoteAppAuthentication(isDefaultScheme: true);
.AddRemoteAppClient(remote => remote
.Configure(options =>
{
options.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);

// A real application would not hard code this, but load it
// securely from environment or configuration
options.ApiKey = "TopSecretString";
})

// This registers the remote app authentication handler. The boolean argument indicates whether remote app auth
// should be the default scheme. If it is set to false, HTTP requests to authenticate will only be made for
// endpoints that actually need that behavior, but it is then necessary to annotate endpoints requiring remote app
// auth with [Authorize(AuthenticationSchemes = RemoteAppAuthenticationDefaults.AuthenticationScheme)] or something similar.
.AddAuthentication(isDefaultScheme: true));

var app = builder.Build();

Expand Down
11 changes: 6 additions & 5 deletions samples/RemoteAuth/Forms/FormsAuth/Global.asax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ void Application_Start(object sender, EventArgs e)

SystemWebAdapterConfiguration.AddSystemWebAdapters(this)
.AddProxySupport(options => options.UseForwardedHeaders = true)
.AddRemoteApp(options =>
{
options.ApiKey = "FormsAuthSampleKey";
})
.AddRemoteAppAuthentication();
.AddRemoteAppServer(remote => remote
.Configure(options =>
{
options.ApiKey = "FormsAuthSampleKey";
})
.AddAuthentication());
}
}
}
14 changes: 7 additions & 7 deletions samples/RemoteAuth/Forms/FormsAuthCore/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Microsoft.AspNetCore.SystemWebAdapters;
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
Expand All @@ -8,12 +7,13 @@

// Add System.Web adapter services, including registering remote app authentication
builder.Services.AddSystemWebAdapters()
.AddRemoteApp(options =>
{
options.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
options.ApiKey = "FormsAuthSampleKey";
})
.AddRemoteAppAuthentication(true);
.AddRemoteAppClient(remote => remote
.Configure(options =>
{
options.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
options.ApiKey = "FormsAuthSampleKey";
})
.AddAuthentication(true));

var app = builder.Build();

Expand Down
8 changes: 3 additions & 5 deletions samples/RemoteAuth/OIDC/OIDCAuth/Global.asax.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
Expand All @@ -19,8 +16,9 @@ protected void Application_Start()

SystemWebAdapterConfiguration.AddSystemWebAdapters(this)
.AddProxySupport(options => options.UseForwardedHeaders = true)
.AddRemoteApp(options => options.ApiKey = "test-key")
.AddRemoteAppAuthentication();
.AddRemoteAppServer(remote => remote
.Configure(options => options.ApiKey = "test-key")
.AddAuthentication());

}
}
Expand Down
14 changes: 7 additions & 7 deletions samples/RemoteAuth/OIDC/OIDCAuthCore/Program.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSystemWebAdapters()
.AddRemoteApp(options =>
{
options.RemoteAppUrl =
new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
options.ApiKey = "test-key";
})
.AddRemoteAppAuthentication(true);
.AddRemoteAppClient(remote => remote
.Configure(options =>
{
options.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
options.ApiKey = "test-key";
})
.AddAuthentication(true));

builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace System.Web;

public static class RemoteAppSessionStateExtensions
{
public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapterBuilder builder, Action<RemoteAppSessionStateOptions>? configureRemote = null)
public static ISystemWebAdapterRemoteServerAppBuilder AddSession(this ISystemWebAdapterRemoteServerAppBuilder builder, Action<RemoteAppSessionStateServerOptions>? configureRemote = null)
{
if (builder is null)
{
Expand All @@ -23,7 +23,7 @@ public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapte
builder.Services.AddOptions<SessionSerializerOptions>()
// We don't want to throw by default on the .NET Framework side as then the error won't be easily visible in the ASP.NET Core app
.Configure(options => options.ThrowOnUnknownSessionKey = false);
var options = builder.Services.AddOptions<RemoteAppSessionStateOptions>();
var options = builder.Services.AddOptions<RemoteAppSessionStateServerOptions>();

if (configureRemote is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ namespace Microsoft.AspNetCore.SystemWebAdapters.SessionState.RemoteSession;
internal sealed class RemoteSessionModule : IHttpModule
{
private readonly RemoteAppOptions _remoteAppOptions;
private readonly RemoteAppSessionStateOptions _sessionOptions;
private readonly RemoteAppSessionStateServerOptions _sessionOptions;
private readonly ReadOnlySessionHandler _readonlyHandler;
private readonly GetWriteableSessionHandler _writeableHandler;
private readonly StoreSessionStateHandler _saveHandler;

public RemoteSessionModule(IOptions<RemoteAppSessionStateOptions> sessionOptions, IOptions<RemoteAppOptions> remoteAppOptions, ILockedSessionCache cache, ISessionSerializer serializer)
public RemoteSessionModule(IOptions<RemoteAppSessionStateServerOptions> sessionOptions, IOptions<RemoteAppOptions> remoteAppOptions, ILockedSessionCache cache, ISessionSerializer serializer)
{
_sessionOptions = sessionOptions?.Value ?? throw new ArgumentNullException(nameof(sessionOptions));
_remoteAppOptions = remoteAppOptions?.Value ?? throw new ArgumentNullException(nameof(remoteAppOptions));
Expand Down Expand Up @@ -78,5 +78,5 @@ public void Dispose()
}

private static bool GetIsReadonly(HttpRequestBase request)
=> bool.TryParse(request.Headers.Get(RemoteAppSessionStateOptions.ReadOnlyHeaderName), out var result) && result;
=> bool.TryParse(request.Headers.Get(SessionConstants.ReadOnlyHeaderName), out var result) && result;
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if !NETFRAMEWORK
using System.ComponentModel.DataAnnotations;
#endif

using System;

namespace Microsoft.AspNetCore.SystemWebAdapters.SessionState.RemoteSession;

public class RemoteAppSessionStateOptions
public class RemoteAppSessionStateClientOptions
{
internal const string ReadOnlyHeaderName = "X-SystemWebAdapter-RemoteAppSession-ReadOnly";

#if !NETFRAMEWORK
[Required]
#endif
public string SessionEndpointPath { get; set; } = "/systemweb-adapters/session";
public string SessionEndpointPath { get; set; } = SessionConstants.SessionEndpointPath;

/// <summary>
/// Gets or sets the cookie name that the ASP.NET framework app is expecting to hold the session id
/// </summary>
#if !NETFRAMEWORK
[Required]
#endif
public string CookieName { get; set; } = "ASP.NET_SessionId";
public string CookieName { get; set; } = SessionConstants.DefaultCookieName;

#if !NETFRAMEWORK
/// <summary>
/// The maximum time loading session state from the remote app
/// or committing changes to it can take before timing out.
/// </summary>
[Required]
public TimeSpan NetworkTimeout { get; set; } = TimeSpan.FromMinutes(1);
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.DependencyInjection;

public static class RemoteAppSessionStateExtensions
{
public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapterBuilder builder, Action<RemoteAppSessionStateOptions>? configure = null)
public static ISystemWebAdapterRemoteClientAppBuilder AddSession(this ISystemWebAdapterRemoteClientAppBuilder builder, Action<RemoteAppSessionStateClientOptions>? configure = null)
{
if (builder is null)
{
Expand All @@ -20,7 +20,7 @@ public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapte
builder.Services.AddHttpClient<ISessionManager, RemoteAppSessionStateManager>()
// Disable cookies in the HTTP client because the service will manage the cookie header directly
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { UseCookies = false });
builder.Services.AddOptions<RemoteAppSessionStateOptions>()
builder.Services.AddOptions<RemoteAppSessionStateClientOptions>()
.Configure(configure ?? (_ => { }))
.ValidateDataAnnotations();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ internal partial class RemoteAppSessionStateManager : ISessionManager
private readonly HttpClient _client;
private readonly ISessionSerializer _serializer;
private readonly ILogger<RemoteAppSessionStateManager> _logger;
private readonly RemoteAppSessionStateOptions _options;
private readonly RemoteAppSessionStateClientOptions _options;

public RemoteAppSessionStateManager(
HttpClient client,
ISessionSerializer serializer,
IOptions<RemoteAppSessionStateOptions> sessionOptions,
IOptions<RemoteAppSessionStateClientOptions> sessionOptions,
IOptions<RemoteAppOptions> remoteAppOptions,
ILogger<RemoteAppSessionStateManager> logger)
{
Expand Down Expand Up @@ -154,7 +154,7 @@ private void AddSessionCookieToHeader(HttpRequestMessage req, string? sessionId)
}

private static void AddReadOnlyHeader(HttpRequestMessage req, bool readOnly)
=> req.Headers.Add(RemoteAppSessionStateOptions.ReadOnlyHeaderName, readOnly.ToString());
=> req.Headers.Add(SessionConstants.ReadOnlyHeaderName, readOnly.ToString());

private class SerializedSessionHttpContent : HttpContent
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.SystemWebAdapters.SessionState.RemoteSession;

public class RemoteAppSessionStateServerOptions
{
public string SessionEndpointPath { get; set; } = SessionConstants.SessionEndpointPath;

/// <summary>
/// Gets or sets the cookie name that the ASP.NET framework app is expecting to hold the session id
/// </summary>
public string CookieName { get; set; } = SessionConstants.DefaultCookieName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.SystemWebAdapters.SessionState;

internal static class SessionConstants
{
public const string ReadOnlyHeaderName = "X-SystemWebAdapter-RemoteAppSession-ReadOnly";

public const string SessionEndpointPath = "/systemweb-adapters/session";

public const string DefaultCookieName = "ASP.NET_SessionId";
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ internal static class AuthenticationConstants
public const string ForwardedProtoHeaderName = "x-forwarded-proto";
public const string MigrationAuthenticateRequestHeaderName = "x-migration-authenticate";
public const string OriginalUrlQueryParamName = "original-url";
public const string DefaultEndpoint = "/systemweb-adapters/authenticate";
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ internal interface IAuthenticationResultFactory
/// <param name="response">The HTTP response from the remote authentication service.</param>
/// <param name="options">Configuration for remote authentication, including response headers to be propagated to the caller.</param>
/// <returns>The result of authenticaiton, including a user identity and/or an HTTP status code and response headers.</returns>
Task<RemoteAppAuthenticationResult> CreateRemoteAppAuthenticationResultAsync(HttpResponseMessage response, RemoteAppAuthenticationOptions options);
Task<RemoteAppAuthenticationResult> CreateRemoteAppAuthenticationResultAsync(HttpResponseMessage response, RemoteAppAuthenticationClientOptions options);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.SystemWebAdapters.Authentication;
/// Authentication handler that authenticates users by making requests to a remote app
/// for authentication via a remote authentication service.
/// </summary>
internal partial class RemoteAppAuthenticationAuthHandler : AuthenticationHandler<RemoteAppAuthenticationOptions>
internal partial class RemoteAppAuthenticationAuthHandler : AuthenticationHandler<RemoteAppAuthenticationClientOptions>
{
private readonly IRemoteAppAuthenticationService _authService;
private readonly IEnumerable<IRemoteAppAuthenticationResultProcessor> _resultProcessors;
Expand All @@ -27,7 +27,7 @@ internal partial class RemoteAppAuthenticationAuthHandler : AuthenticationHandle

public RemoteAppAuthenticationAuthHandler(IRemoteAppAuthenticationService authService,
IEnumerable<IRemoteAppAuthenticationResultProcessor> resultProcessors,
IOptionsMonitor<RemoteAppAuthenticationOptions> options,
IOptionsMonitor<RemoteAppAuthenticationClientOptions> options,
ILoggerFactory loggerFactory,
UrlEncoder encoder,
ISystemClock clock)
Expand Down
Loading