Add Basic auth tests and fix Windows auth tests (#1502)

This commit is contained in:
Pavel Krymets 2018-10-12 12:03:11 -07:00 committed by GitHub
parent fc40985dff
commit 642e8e9d7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 147 additions and 79 deletions

View File

@ -41,14 +41,40 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
});
}
public static void AddWindowsAuthToServerConfig(this IISDeploymentParameters parameters)
public static void SetWindowsAuth(this IISDeploymentParameters parameters, bool enabled = true)
{
parameters.EnableModule("WindowsAuthenticationModule", "%IIS_BIN%\\authsspi.dll");
parameters.AddServerConfigAction(
element =>
{
element.Descendants("windowsAuthentication")
.Single()
.SetAttributeValue("enabled", "true");
.SetAttributeValue("enabled", enabled);
});
}
public static void SetAnonymousAuth(this IISDeploymentParameters parameters, bool enabled = true)
{
parameters.AddServerConfigAction(
element =>
{
element.Descendants("anonymousAuthentication")
.Single()
.SetAttributeValue("enabled", enabled);
});
}
public static void SetBasicAuth(this IISDeploymentParameters parameters, bool enabled = true)
{
parameters.EnableModule("BasicAuthenticationModule", "%IIS_BIN%\\authbas.dll");
parameters.AddServerConfigAction(
element =>
{
element.Descendants("basicAuthentication")
.Single()
.SetAttributeValue("enabled", enabled);
});
}

View File

@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
response = await deploymentResult.HttpClient.GetAsync("/Auth");
responseText = await response.Content.ReadAsStringAsync();
Assert.True("null".Equals(responseText), "Auth");
Assert.Equal("null", responseText);
Assert.Equal(
$"ContentRootPath {deploymentResult.ContentRoot}" + Environment.NewLine +

View File

@ -16,6 +16,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
DynamicCompression = 16,
ApplicationInitialization = 32,
TracingModule = 64,
FailedRequestTracingModule = 128
FailedRequestTracingModule = 128,
BasicAuthentication = 256
}
}

View File

@ -15,16 +15,21 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
public sealed class RequiresIISAttribute : Attribute, ITestCondition
{
private static readonly (IISCapability Capability, string DllName)[] Modules =
{
(IISCapability.Websockets, "iiswsock.dll"),
(IISCapability.WindowsAuthentication, "authsspi.dll"),
(IISCapability.DynamicCompression, "compdyn.dll"),
(IISCapability.ApplicationInitialization, "warmup.dll"),
(IISCapability.TracingModule, "iisetw.dll"),
(IISCapability.FailedRequestTracingModule, "iisfreb.dll"),
(IISCapability.BasicAuthentication, "authbas.dll"),
};
private static readonly bool _isMetStatic;
private static readonly string _skipReasonStatic;
private static readonly bool _websocketsAvailable;
private static readonly bool _windowsAuthAvailable;
private static readonly bool _poolEnvironmentVariablesAvailable;
private static readonly bool _dynamicCompressionAvailable;
private static readonly bool _applicationInitializationModule;
private static readonly bool _tracingModuleAvailable;
private static readonly bool _frebTracingModuleAvailable;
private static readonly IISCapability _modulesAvailable;
static RequiresIISAttribute()
{
@ -81,18 +86,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
_skipReasonStatic = _isMetStatic ? null : "IIS schema needs to be upgraded to support ANCM.";
_websocketsAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "iiswsock.dll"));
_windowsAuthAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "authsspi.dll"));
_dynamicCompressionAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "compdyn.dll"));
_applicationInitializationModule = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "warmup.dll"));
_tracingModuleAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "iisetw.dll"));
_frebTracingModuleAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "iisfreb.dll"));
foreach (var module in Modules)
{
if (File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", module.DllName)))
{
_modulesAvailable |= module.Capability;
}
}
var iisRegistryKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\InetStp", writable: false);
if (iisRegistryKey == null)
@ -115,23 +115,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
IsMet = _isMetStatic;
SkipReason = _skipReasonStatic;
if (capabilities.HasFlag(IISCapability.Websockets))
{
IsMet &= _websocketsAvailable;
if (!_websocketsAvailable)
{
SkipReason += "The machine does not have IIS websockets installed.";
}
}
if (capabilities.HasFlag(IISCapability.WindowsAuthentication))
{
IsMet &= _windowsAuthAvailable;
if (!_windowsAuthAvailable)
{
SkipReason += "The machine does not have IIS windows authentication installed.";
}
}
if (capabilities.HasFlag(IISCapability.PoolEnvironmentVariables))
{
IsMet &= _poolEnvironmentVariablesAvailable;
@ -147,40 +130,16 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
SkipReason += "https://github.com/aspnet/IISIntegration/issues/1074";
}
if (capabilities.HasFlag(IISCapability.DynamicCompression))
foreach (var module in Modules)
{
IsMet &= _dynamicCompressionAvailable;
if (!_dynamicCompressionAvailable)
if (capabilities.HasFlag(module.Capability))
{
SkipReason += "The machine does not have IIS dynamic compression installed.";
}
}
if (capabilities.HasFlag(IISCapability.ApplicationInitialization))
{
IsMet &= _applicationInitializationModule;
if (!_applicationInitializationModule)
{
SkipReason += "The machine does not have IIS ApplicationInitialization installed.";
}
}
if (capabilities.HasFlag(IISCapability.TracingModule))
{
IsMet &= _tracingModuleAvailable;
if (!_tracingModuleAvailable)
{
SkipReason += "The machine does not have IIS Failed Request Tracing Module installed.";
}
}
if (capabilities.HasFlag(IISCapability.FailedRequestTracingModule))
{
IsMet &= _frebTracingModuleAvailable;
if (!_frebTracingModuleAvailable)
{
SkipReason += "The machine does not have IIS Failed Request Tracing Module installed.";
var available = _modulesAvailable.HasFlag(module.Capability);
IsMet &= available;
if (!available)
{
SkipReason += $"The machine does have {module.Capability} available.";
}
}
}
}

View File

@ -0,0 +1,70 @@
// 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.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.AspNetCore.Testing.xunit;
using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
[Collection(PublishedSitesCollection.Name)]
public class BasicAuthTests : IISFunctionalTestBase
{
private readonly PublishedSitesFixture _fixture;
public BasicAuthTests(PublishedSitesFixture fixture)
{
_fixture = fixture;
}
public static TestMatrix TestVariants
=> TestMatrix.ForServers(DeployerSelector.ServerType)
.WithTfms(Tfm.NetCoreApp22)
.WithApplicationTypes(ApplicationType.Portable)
.WithAllAncmVersions()
.WithAllHostingModels();
[ConditionalTheory(Skip = "This test is manual. To run it set ASPNETCORE_MODULE_TEST_USER and ASPNETCORE_MODULE_TEST_PASSWORD environment variables to existing user")]
[RequiresIIS(IISCapability.BasicAuthentication)]
[MemberData(nameof(TestVariants))]
public async Task BasicAuthTest(TestVariant variant)
{
var username = Environment.GetEnvironmentVariable("ASPNETCORE_MODULE_TEST_USER");
var password = Environment.GetEnvironmentVariable("ASPNETCORE_MODULE_TEST_PASSWORD");
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
deploymentParameters.SetAnonymousAuth(enabled: false);
deploymentParameters.SetWindowsAuth(enabled: false);
deploymentParameters.SetBasicAuth(enabled: true);
// The default in hosting sets windows auth to true.
var deploymentResult = await DeployAsync(deploymentParameters);
var request = new HttpRequestMessage(HttpMethod.Get, "/Auth");
var byteArray = new UTF8Encoding().GetBytes(username + ":" + password);
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var response = await deploymentResult.HttpClient.SendAsync(request);
var responseText = await response.Content.ReadAsStringAsync();
if (variant.HostingModel == HostingModel.InProcess)
{
Assert.StartsWith("Windows", responseText);
Assert.Contains(username, responseText);
}
else
{
// We expect out-of-proc not allowing basic auth
Assert.Equal("Windows:", responseText);
}
}
}
}

View File

@ -22,10 +22,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
}
[ConditionalFact]
[RequiresIIS(IISCapability.WindowsAuthentication)]
public async Task Authentication_InProcess()
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
deploymentParameters.AddWindowsAuthToServerConfig();
deploymentParameters.SetWindowsAuth();
var deploymentResult = await DeployAsync(deploymentParameters);

View File

@ -34,13 +34,14 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
.WithAllAncmVersions();
[ConditionalTheory]
[RequiresIIS(IISCapability.WindowsAuthentication)]
[MemberData(nameof(TestVariants))]
public async Task NtlmAuthentication(TestVariant variant)
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
deploymentParameters.ApplicationBaseUriHint = $"https://localhost:0/";
deploymentParameters.AddWindowsAuthToServerConfig();
deploymentParameters.SetWindowsAuth(enabled: true);
var result = await DeployAsync(deploymentParameters);
var response = await result.HttpClient.GetAsync("/HelloWorld");

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public RequiresIISAttribute(IISCapability capabilities)
{
// IISCapabilities aren't pretinent to IISExpress
// IISCapabilities aren't pertinent to IISExpress
}
}
}

View File

@ -1,6 +1,8 @@
// 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.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
@ -23,24 +25,28 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public static TestMatrix TestVariants
=> TestMatrix.ForServers(DeployerSelector.ServerType)
.WithTfms(Tfm.NetCoreApp22, Tfm.Net461)
.WithAllApplicationTypes()
.WithApplicationTypes(ApplicationType.Portable)
.WithAllAncmVersions()
.WithAllHostingModels();
[ConditionalTheory]
[RequiresIIS(IISCapability.WindowsAuthentication)]
[MemberData(nameof(TestVariants))]
public async Task WindowsAuthTest(TestVariant variant)
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
deploymentParameters.AddWindowsAuthToServerConfig();
deploymentParameters.SetAnonymousAuth(enabled: false);
deploymentParameters.SetWindowsAuth();
// The default in hosting sets windows auth to true.
var deploymentResult = await DeployAsync(deploymentParameters);
var response = await deploymentResult.HttpClient.GetAsync("/Auth");
var client = deploymentResult.CreateClient(new HttpClientHandler { UseDefaultCredentials = true });
var response = await client.GetAsync("/Auth");
var responseText = await response.Content.ReadAsStringAsync();
Assert.Equal("Windows", responseText);
Assert.StartsWith("Windows:", responseText);
Assert.Contains(Environment.UserName, responseText);
}
}
}

View File

@ -44,6 +44,10 @@ namespace TestSite
var authScheme = (await authProvider.GetAllSchemesAsync()).SingleOrDefault();
await ctx.Response.WriteAsync(authScheme?.Name ?? "null");
if (ctx.User.Identity.Name != null)
{
await ctx.Response.WriteAsync(":" + ctx.User.Identity.Name);
}
}
public async Task GetClientCert(HttpContext context)