Merge branch 'merge/release/2.2-to-master'

This commit is contained in:
Pavel Krymets 2018-10-12 15:54:01 -07:00
commit a7e58eefdc
11 changed files with 147 additions and 82 deletions

View File

@ -1,7 +1,6 @@
import org.dotnet.ci.pipelines.Pipeline import org.dotnet.ci.pipelines.Pipeline
def windowsPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/windows.groovy') def windowsPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/windows.groovy')
def windowsAppverifPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/windows-appverif.groovy')
def configurations = [ def configurations = [
'Debug', 'Debug',
@ -16,6 +15,4 @@ configurations.each { configuration ->
windowsPipeline.triggerPipelineOnEveryGithubPR("Windows ${configuration} x64 Build", params) windowsPipeline.triggerPipelineOnEveryGithubPR("Windows ${configuration} x64 Build", params)
windowsPipeline.triggerPipelineOnGithubPush(params) windowsPipeline.triggerPipelineOnGithubPush(params)
windowsAppverifPipeline.triggerPipelineOnEveryGithubPR("Windows AppVerifier ${configuration} x64 Build", params)
} }

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( parameters.AddServerConfigAction(
element => element =>
{ {
element.Descendants("windowsAuthentication") element.Descendants("windowsAuthentication")
.Single() .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"); response = await deploymentResult.HttpClient.GetAsync("/Auth");
responseText = await response.Content.ReadAsStringAsync(); responseText = await response.Content.ReadAsStringAsync();
Assert.True("null".Equals(responseText), "Auth"); Assert.Equal("null", responseText);
Assert.Equal( Assert.Equal(
$"ContentRootPath {deploymentResult.ContentRoot}" + Environment.NewLine + $"ContentRootPath {deploymentResult.ContentRoot}" + Environment.NewLine +

View File

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

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] [ConditionalFact]
[RequiresIIS(IISCapability.WindowsAuthentication)]
public async Task Authentication_InProcess() public async Task Authentication_InProcess()
{ {
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
deploymentParameters.AddWindowsAuthToServerConfig(); deploymentParameters.SetWindowsAuth();
var deploymentResult = await DeployAsync(deploymentParameters); var deploymentResult = await DeployAsync(deploymentParameters);

View File

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

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public RequiresIISAttribute(IISCapability capabilities) 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. // 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. // 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 System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Server.IntegrationTesting;
@ -23,24 +25,28 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public static TestMatrix TestVariants public static TestMatrix TestVariants
=> TestMatrix.ForServers(DeployerSelector.ServerType) => TestMatrix.ForServers(DeployerSelector.ServerType)
.WithTfms(Tfm.NetCoreApp22, Tfm.Net461) .WithTfms(Tfm.NetCoreApp22, Tfm.Net461)
.WithAllApplicationTypes() .WithApplicationTypes(ApplicationType.Portable)
.WithAllAncmVersions() .WithAllAncmVersions()
.WithAllHostingModels(); .WithAllHostingModels();
[ConditionalTheory] [ConditionalTheory]
[RequiresIIS(IISCapability.WindowsAuthentication)]
[MemberData(nameof(TestVariants))] [MemberData(nameof(TestVariants))]
public async Task WindowsAuthTest(TestVariant variant) public async Task WindowsAuthTest(TestVariant variant)
{ {
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant); var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
deploymentParameters.AddWindowsAuthToServerConfig(); deploymentParameters.SetAnonymousAuth(enabled: false);
deploymentParameters.SetWindowsAuth();
// The default in hosting sets windows auth to true. // The default in hosting sets windows auth to true.
var deploymentResult = await DeployAsync(deploymentParameters); 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(); 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(); var authScheme = (await authProvider.GetAllSchemesAsync()).SingleOrDefault();
await ctx.Response.WriteAsync(authScheme?.Name ?? "null"); 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) public async Task GetClientCert(HttpContext context)