#371 Conditionally register auth scheme base on ANCM variable
This commit is contained in:
parent
16c70d6dda
commit
c261b37fda
|
|
@ -5,6 +5,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
{
|
||||
public class IISDefaults
|
||||
{
|
||||
public static readonly string AuthenticationScheme = "Windows";
|
||||
public const string Negotiate = "Negotiate";
|
||||
public const string Ntlm = "NTLM";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
{
|
||||
public class IISMiddleware
|
||||
{
|
||||
public static readonly string AuthenticationScheme = "Windows";
|
||||
|
||||
private const string MSAspNetCoreClientCert = "MS-ASPNETCORE-CLIENTCERT";
|
||||
private const string MSAspNetCoreToken = "MS-ASPNETCORE-TOKEN";
|
||||
|
||||
|
|
@ -50,10 +48,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
_next = next;
|
||||
_options = options.Value;
|
||||
|
||||
|
||||
if (_options.ForwardWindowsAuthentication)
|
||||
{
|
||||
authentication.AddScheme(new AuthenticationScheme(AuthenticationScheme, displayName: null, handlerType: typeof(AuthenticationHandler)));
|
||||
authentication.AddScheme(new AuthenticationScheme(IISDefaults.AuthenticationScheme, displayName: null, handlerType: typeof(AuthenticationHandler)));
|
||||
}
|
||||
|
||||
_pairingToken = pairingToken;
|
||||
|
|
@ -94,7 +91,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
|
||||
if (_options.ForwardWindowsAuthentication)
|
||||
{
|
||||
var result = await httpContext.AuthenticateAsync(AuthenticationScheme);
|
||||
var result = await httpContext.AuthenticateAsync(IISDefaults.AuthenticationScheme);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
httpContext.User = result.Principal;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
|
|
@ -6,14 +6,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public class IISOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// If true authentication middleware will try to authenticate using platform handler windows authentication
|
||||
/// If false authentication middleware won't be added
|
||||
/// If true authentication middleware will try to authenticate using AspNetCoreModule windows authentication
|
||||
/// If false authentication components won't be added
|
||||
/// </summary>
|
||||
public bool ForwardWindowsAuthentication { get; set; } = true;
|
||||
internal bool ForwardWindowsAuthentication { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Populates the ITLSConnectionFeature if the MS-ASPNETCORE-CLIENTCERT request header is present.
|
||||
/// </summary>
|
||||
public bool ForwardClientCertificate { get; set; } = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
|
@ -17,6 +18,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
private static readonly string ServerPort = "PORT";
|
||||
private static readonly string ServerPath = "APPL_PATH";
|
||||
private static readonly string PairingToken = "TOKEN";
|
||||
private static readonly string IISAuth = "IIS_HTTPAUTH";
|
||||
|
||||
/// <summary>
|
||||
/// Configures the port and base path the server should listen on when running behind AspNetCoreModule.
|
||||
|
|
@ -40,12 +42,32 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
var port = hostBuilder.GetSetting(ServerPort) ?? Environment.GetEnvironmentVariable($"ASPNETCORE_{ServerPort}");
|
||||
var path = hostBuilder.GetSetting(ServerPath) ?? Environment.GetEnvironmentVariable($"ASPNETCORE_{ServerPath}");
|
||||
var pairingToken = hostBuilder.GetSetting(PairingToken) ?? Environment.GetEnvironmentVariable($"ASPNETCORE_{PairingToken}");
|
||||
var iisAuth = hostBuilder.GetSetting(IISAuth) ?? Environment.GetEnvironmentVariable($"ASPNETCORE_{IISAuth}");
|
||||
|
||||
if (!string.IsNullOrEmpty(port) && !string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(pairingToken))
|
||||
{
|
||||
// Set flag to prevent double service configuration
|
||||
hostBuilder.UseSetting(nameof(UseIISIntegration), true.ToString());
|
||||
|
||||
var enableAuth = false;
|
||||
if (string.IsNullOrEmpty(iisAuth))
|
||||
{
|
||||
// back compat with older ANCM versions
|
||||
enableAuth = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lightup a new ANCM variable that tells us if auth is enabled.
|
||||
foreach (var authType in iisAuth.Split(';'))
|
||||
{
|
||||
if (!string.Equals(authType, "anonymous", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
enableAuth = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var address = "http://localhost:" + port;
|
||||
hostBuilder.CaptureStartupErrors(true);
|
||||
|
||||
|
|
@ -59,6 +81,10 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
{
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||
});
|
||||
services.Configure<IISOptions>(options =>
|
||||
{
|
||||
options.ForwardWindowsAuthentication = enableAuth;
|
||||
});
|
||||
services.AddAuthenticationCore();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
response = await deploymentResult.HttpClient.GetAsync("/BodyLimit");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("null", responseText);
|
||||
|
||||
response = await deploymentResult.HttpClient.GetAsync("/Auth");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.True("backcompat;Windows".Equals(responseText) || "latest;null".Equals(responseText), "Auth");
|
||||
}
|
||||
catch (XunitException)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
app.Run(async context =>
|
||||
{
|
||||
var auth = context.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
|
||||
var windows = await auth.GetSchemeAsync(IISMiddleware.AuthenticationScheme);
|
||||
var windows = await auth.GetSchemeAsync(IISDefaults.AuthenticationScheme);
|
||||
Assert.NotNull(windows);
|
||||
Assert.Null(windows.DisplayName);
|
||||
Assert.Equal("Microsoft.AspNetCore.Server.IISIntegration.AuthenticationHandler", windows.HandlerType.FullName);
|
||||
|
|
@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
|
|||
{
|
||||
var auth = context.RequestServices.GetService<IAuthenticationSchemeProvider>();
|
||||
Assert.NotNull(auth);
|
||||
var windowsAuth = await auth.GetSchemeAsync(IISMiddleware.AuthenticationScheme);
|
||||
var windowsAuth = await auth.GetSchemeAsync(IISDefaults.AuthenticationScheme);
|
||||
if (forward)
|
||||
{
|
||||
Assert.NotNull(windowsAuth);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace TestSites
|
||||
|
|
@ -12,23 +16,42 @@ namespace TestSites
|
|||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
app.Run(ctx =>
|
||||
app.Run(async ctx =>
|
||||
{
|
||||
if (ctx.Request.Path.Value.StartsWith("/Path"))
|
||||
{
|
||||
return ctx.Response.WriteAsync(ctx.Request.Path.Value);
|
||||
await ctx.Response.WriteAsync(ctx.Request.Path.Value);
|
||||
return;
|
||||
}
|
||||
if (ctx.Request.Path.Value.StartsWith("/Query"))
|
||||
{
|
||||
return ctx.Response.WriteAsync(ctx.Request.QueryString.Value);
|
||||
await ctx.Response.WriteAsync(ctx.Request.QueryString.Value);
|
||||
return;
|
||||
}
|
||||
if (ctx.Request.Path.Value.StartsWith("/BodyLimit"))
|
||||
{
|
||||
return ctx.Response.WriteAsync(
|
||||
await ctx.Response.WriteAsync(
|
||||
ctx.Features.Get<IHttpMaxRequestBodySizeFeature>()?.MaxRequestBodySize?.ToString() ?? "null");
|
||||
return;
|
||||
}
|
||||
|
||||
return ctx.Response.WriteAsync("Hello World");
|
||||
if (ctx.Request.Path.StartsWithSegments("/Auth"))
|
||||
{
|
||||
var iisAuth = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_HTTPAUTH");
|
||||
var authProvider = ctx.RequestServices.GetService<IAuthenticationSchemeProvider>();
|
||||
var authScheme = (await authProvider.GetAllSchemesAsync()).SingleOrDefault();
|
||||
if (string.IsNullOrEmpty(iisAuth))
|
||||
{
|
||||
await ctx.Response.WriteAsync("backcompat;" + authScheme?.Name ?? "null");
|
||||
}
|
||||
else
|
||||
{
|
||||
await ctx.Response.WriteAsync("latest;" + authScheme?.Name ?? "null");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.Response.WriteAsync("Hello World");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace TestSites
|
|||
}
|
||||
else
|
||||
{
|
||||
return context.ChallengeAsync(IISMiddleware.AuthenticationScheme);
|
||||
return context.ChallengeAsync(IISDefaults.AuthenticationScheme);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue