#95 Switch the middleware from HttpPlatfromHandler to AspNetCoreModule.
This commit is contained in:
parent
3e7efd04da
commit
126ed6c4de
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
|
|
@ -15,10 +14,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.IISPla
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{EF30B533-D715-421A-92B7-92FEF460AC9C}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.IISPlatformHandler.Tests", "test\Microsoft.AspNetCore.IISPlatformHandler.Tests\Microsoft.AspNetCore.IISPlatformHandler.Tests.xproj", "{FBBBE015-1CE3-454B-9647-23F8073FB7AB}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests", "test\Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests\Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests.xproj", "{A83A33D1-3D29-403C-9750-5811AC7B4025}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestSites", "test\TestSites\TestSites.xproj", "{E27453AD-9CA0-49A2-94FA-96337D77677D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}"
|
||||
|
|
@ -29,6 +24,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-publish-iis.Tests",
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-publish-iis", "src\dotnet-publish-iis\dotnet-publish-iis.xproj", "{E492AEF2-42C1-4399-B718-A6934EBB36AB}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Server.IISIntegration", "src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.xproj", "{8B3446E8-E6A8-4591-AA63-A95837C6E97C}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests", "test\Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests\Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests.xproj", "{7F2F50C7-610F-4B69-B945-CA283511A587}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Server.IISIntegration.Tests", "test\Microsoft.AspNetCore.Server.IISIntegration.Tests\Microsoft.AspNetCore.Server.IISIntegration.Tests.xproj", "{4106DB10-E09F-480E-9CE6-B39235512EE6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -39,14 +40,6 @@ Global
|
|||
{ABE53415-83CE-4AF0-AF67-E52160C7862B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ABE53415-83CE-4AF0-AF67-E52160C7862B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ABE53415-83CE-4AF0-AF67-E52160C7862B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FBBBE015-1CE3-454B-9647-23F8073FB7AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FBBBE015-1CE3-454B-9647-23F8073FB7AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FBBBE015-1CE3-454B-9647-23F8073FB7AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FBBBE015-1CE3-454B-9647-23F8073FB7AB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A83A33D1-3D29-403C-9750-5811AC7B4025}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A83A33D1-3D29-403C-9750-5811AC7B4025}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A83A33D1-3D29-403C-9750-5811AC7B4025}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A83A33D1-3D29-403C-9750-5811AC7B4025}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E27453AD-9CA0-49A2-94FA-96337D77677D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E27453AD-9CA0-49A2-94FA-96337D77677D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E27453AD-9CA0-49A2-94FA-96337D77677D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -63,17 +56,30 @@ Global
|
|||
{E492AEF2-42C1-4399-B718-A6934EBB36AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E492AEF2-42C1-4399-B718-A6934EBB36AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E492AEF2-42C1-4399-B718-A6934EBB36AB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7F2F50C7-610F-4B69-B945-CA283511A587}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7F2F50C7-610F-4B69-B945-CA283511A587}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F2F50C7-610F-4B69-B945-CA283511A587}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F2F50C7-610F-4B69-B945-CA283511A587}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{ABE53415-83CE-4AF0-AF67-E52160C7862B} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{FBBBE015-1CE3-454B-9647-23F8073FB7AB} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{A83A33D1-3D29-403C-9750-5811AC7B4025} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{E27453AD-9CA0-49A2-94FA-96337D77677D} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
|
||||
{CFB3AF72-0AF6-44CB-8815-6E4052C7B5A0} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{E492AEF2-42C1-4399-B718-A6934EBB36AB} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{8B3446E8-E6A8-4591-AA63-A95837C6E97C} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{7F2F50C7-610F-4B69-B945-CA283511A587} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace IISSample
|
|||
|
||||
var logger = loggerfactory.CreateLogger("Requests");
|
||||
|
||||
app.UseIISPlatformHandler();
|
||||
app.UseIIS();
|
||||
|
||||
app.Run(async (context) =>
|
||||
{
|
||||
|
|
@ -49,7 +49,7 @@ namespace IISSample
|
|||
var host = new WebHostBuilder()
|
||||
.UseDefaultConfiguration(args)
|
||||
.UseServer("Microsoft.AspNetCore.Server.Kestrel")
|
||||
.UseIISPlatformHandlerUrl()
|
||||
.UseIISUrl()
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.IISPlatformHandler": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*",
|
||||
"Microsoft.Extensions.Logging.Console": "1.0.0-*",
|
||||
"Microsoft.NETCore.Platforms": "1.0.1-*"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
|
||||
<aspNetCore processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600" />
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
// 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 System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||
{
|
||||
internal class AuthenticationHandler : IAuthenticationHandler
|
||||
{
|
||||
internal AuthenticationHandler(HttpContext httpContext, IISOptions options, ClaimsPrincipal user)
|
||||
{
|
||||
HttpContext = httpContext;
|
||||
User = user;
|
||||
Options = options;
|
||||
}
|
||||
|
||||
internal HttpContext HttpContext { get; }
|
||||
|
||||
internal IISOptions Options { get; }
|
||||
|
||||
internal ClaimsPrincipal User { get; }
|
||||
|
||||
internal IAuthenticationHandler PriorHandler { get; set; }
|
||||
|
||||
public Task AuthenticateAsync(AuthenticateContext context)
|
||||
{
|
||||
if (ShouldHandleScheme(context.AuthenticationScheme))
|
||||
{
|
||||
if (User != null)
|
||||
{
|
||||
context.Authenticated(User, properties: null,
|
||||
description: Options.AuthenticationDescriptions.FirstOrDefault(descrip =>
|
||||
string.Equals(User.Identity.AuthenticationType, descrip.AuthenticationScheme, StringComparison.Ordinal))?.Items);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.NotAuthenticated();
|
||||
}
|
||||
}
|
||||
|
||||
if (PriorHandler != null)
|
||||
{
|
||||
return PriorHandler.AuthenticateAsync(context);
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task ChallengeAsync(ChallengeContext context)
|
||||
{
|
||||
bool handled = false;
|
||||
if (ShouldHandleScheme(context.AuthenticationScheme))
|
||||
{
|
||||
switch (context.Behavior)
|
||||
{
|
||||
case ChallengeBehavior.Automatic:
|
||||
// If there is a principal already, invoke the forbidden code path
|
||||
if (User == null)
|
||||
{
|
||||
goto case ChallengeBehavior.Unauthorized;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto case ChallengeBehavior.Forbidden;
|
||||
}
|
||||
case ChallengeBehavior.Unauthorized:
|
||||
HttpContext.Response.StatusCode = 401;
|
||||
// We would normally set the www-authenticate header here, but IIS does that for us.
|
||||
break;
|
||||
case ChallengeBehavior.Forbidden:
|
||||
HttpContext.Response.StatusCode = 403;
|
||||
handled = true; // No other handlers need to consider this challenge.
|
||||
break;
|
||||
}
|
||||
context.Accept();
|
||||
}
|
||||
|
||||
if (!handled && PriorHandler != null)
|
||||
{
|
||||
return PriorHandler.ChallengeAsync(context);
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public void GetDescriptions(DescribeSchemesContext context)
|
||||
{
|
||||
foreach (var description in Options.AuthenticationDescriptions)
|
||||
{
|
||||
context.Accept(description.Items);
|
||||
}
|
||||
|
||||
if (PriorHandler != null)
|
||||
{
|
||||
PriorHandler.GetDescriptions(context);
|
||||
}
|
||||
}
|
||||
|
||||
public Task SignInAsync(SignInContext context)
|
||||
{
|
||||
// Not supported, fall through
|
||||
if (PriorHandler != null)
|
||||
{
|
||||
return PriorHandler.SignInAsync(context);
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SignOutAsync(SignOutContext context)
|
||||
{
|
||||
// Not supported, fall through
|
||||
if (PriorHandler != null)
|
||||
{
|
||||
return PriorHandler.SignOutAsync(context);
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
private bool ShouldHandleScheme(string authenticationScheme)
|
||||
{
|
||||
if (Options.AutomaticAuthentication && string.Equals(AuthenticationManager.AutomaticScheme, authenticationScheme, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Options.AuthenticationDescriptions.Any(description => string.Equals(description.AuthenticationScheme, authenticationScheme, StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// 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.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||
{
|
||||
internal class ForwardedTlsConnectionFeature : ITlsConnectionFeature
|
||||
{
|
||||
private StringValues _header;
|
||||
private X509Certificate2 _certificate;
|
||||
private ILogger _logger;
|
||||
|
||||
public ForwardedTlsConnectionFeature(ILogger logger, StringValues header)
|
||||
{
|
||||
_logger = logger;
|
||||
_header = header;
|
||||
}
|
||||
|
||||
public X509Certificate2 ClientCertificate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_certificate == null && _header != StringValues.Empty)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bytes = Convert.FromBase64String(_header);
|
||||
_certificate = new X509Certificate2(bytes);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(0, ex, "Failed to read the client certificate.");
|
||||
}
|
||||
}
|
||||
return _certificate;
|
||||
}
|
||||
set
|
||||
{
|
||||
_certificate = value;
|
||||
_header = StringValues.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(ClientCertificate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
public static class IISAddressExtensions
|
||||
{
|
||||
// This is defined by IIS's AspNetCoreModule.
|
||||
private static readonly string ServerPort = "ASPNETCORE_PORT";
|
||||
private static readonly string ServerPath = "ASPNETCORE_APPL_PATH";
|
||||
|
||||
/// <summary>
|
||||
/// Configures the port and base path the server should listen on when running behind AspNetCoreModule.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
public static IWebHostBuilder UseIISUrl(this IWebHostBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
var port = Environment.GetEnvironmentVariable(ServerPort);
|
||||
var path = Environment.GetEnvironmentVariable(ServerPath);
|
||||
|
||||
if (!string.IsNullOrEmpty(port))
|
||||
{
|
||||
var address = "http://localhost:" + port + path;
|
||||
app.UseSetting(WebHostDefaults.ServerUrlsKey, address);
|
||||
}
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// 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.Server.IISIntegration
|
||||
{
|
||||
public class IISDefaults
|
||||
{
|
||||
public const string Negotiate = "Negotiate";
|
||||
public const string Ntlm = "NTLM";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
// 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.Globalization;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication.Internal;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||
{
|
||||
public class IISMiddleware
|
||||
{
|
||||
private const string MSAspNetCoreWinAuthToken = "MS-ASPNETCORE-WINAUTHTOKEN";
|
||||
private const string MSAspNetCoreClientCert = "MS-ASPNETCORE-CLIENTCERT";
|
||||
private const string AspNetCoreToken = "ASPNETCORE_TOKEN";
|
||||
private const string MSAspNetCoreToken = "MS-ASPNETCORE-TOKEN";
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IISOptions _options;
|
||||
private readonly ILogger _logger;
|
||||
private readonly string _platformToken;
|
||||
|
||||
public IISMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IOptions<IISOptions> options)
|
||||
{
|
||||
if (next == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(next));
|
||||
}
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
_next = next;
|
||||
_options = options.Value;
|
||||
_logger = loggerFactory.CreateLogger<IISMiddleware>();
|
||||
|
||||
_platformToken = Environment.GetEnvironmentVariable(AspNetCoreToken);
|
||||
if (string.IsNullOrEmpty(_platformToken))
|
||||
{
|
||||
_logger.LogInformation($"{AspNetCoreToken} not detected, {nameof(IISMiddleware)} will be skipped.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_platformToken)
|
||||
|| !string.Equals(_platformToken, httpContext.Request.Headers[MSAspNetCoreToken], StringComparison.Ordinal))
|
||||
{
|
||||
_logger.LogTrace($"{MSAspNetCoreToken} not detected, skipping {nameof(IISMiddleware)}.");
|
||||
await _next(httpContext);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_options.ForwardClientCertificate)
|
||||
{
|
||||
var header = httpContext.Request.Headers[MSAspNetCoreClientCert];
|
||||
if (!StringValues.IsNullOrEmpty(header))
|
||||
{
|
||||
httpContext.Features.Set<ITlsConnectionFeature>(new ForwardedTlsConnectionFeature(_logger, header));
|
||||
}
|
||||
}
|
||||
|
||||
if (_options.ForwardWindowsAuthentication)
|
||||
{
|
||||
var winPrincipal = UpdateUser(httpContext);
|
||||
var handler = new AuthenticationHandler(httpContext, _options, winPrincipal);
|
||||
AttachAuthenticationHandler(handler);
|
||||
try
|
||||
{
|
||||
await _next(httpContext);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DetachAuthenticationhandler(handler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(httpContext);
|
||||
}
|
||||
}
|
||||
|
||||
private WindowsPrincipal UpdateUser(HttpContext httpContext)
|
||||
{
|
||||
var tokenHeader = httpContext.Request.Headers[MSAspNetCoreWinAuthToken];
|
||||
|
||||
int hexHandle;
|
||||
WindowsPrincipal winPrincipal = null;
|
||||
if (!StringValues.IsNullOrEmpty(tokenHeader)
|
||||
&& int.TryParse(tokenHeader, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hexHandle))
|
||||
{
|
||||
// Always create the identity if the handle exists, we need to dispose it so it does not leak.
|
||||
var handle = new IntPtr(hexHandle);
|
||||
var winIdentity = new WindowsIdentity(handle);
|
||||
|
||||
// WindowsIdentity just duplicated the handle so we need to close the original.
|
||||
NativeMethods.CloseHandle(handle);
|
||||
|
||||
httpContext.Response.RegisterForDispose(winIdentity);
|
||||
winPrincipal = new WindowsPrincipal(winIdentity);
|
||||
|
||||
if (_options.AutomaticAuthentication)
|
||||
{
|
||||
// Don't get it from httpContext.User, that always returns a non-null anonymous user by default.
|
||||
var existingPrincipal = httpContext.Features.Get<IHttpAuthenticationFeature>()?.User;
|
||||
if (existingPrincipal != null)
|
||||
{
|
||||
httpContext.User = SecurityHelper.MergeUserPrincipal(existingPrincipal, winPrincipal);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpContext.User = winPrincipal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return winPrincipal;
|
||||
}
|
||||
|
||||
private void AttachAuthenticationHandler(AuthenticationHandler handler)
|
||||
{
|
||||
var auth = handler.HttpContext.Features.Get<IHttpAuthenticationFeature>();
|
||||
if (auth == null)
|
||||
{
|
||||
auth = new HttpAuthenticationFeature();
|
||||
handler.HttpContext.Features.Set(auth);
|
||||
}
|
||||
handler.PriorHandler = auth.Handler;
|
||||
auth.Handler = handler;
|
||||
}
|
||||
|
||||
private void DetachAuthenticationhandler(AuthenticationHandler handler)
|
||||
{
|
||||
var auth = handler.HttpContext.Features.Get<IHttpAuthenticationFeature>();
|
||||
if (auth != null)
|
||||
{
|
||||
auth.Handler = handler.PriorHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// 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 Microsoft.AspNetCore.Server.IISIntegration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class IISMiddlewareExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds middleware for interacting with the IIS AspNetCoreModule reverse proxy module.
|
||||
/// This will handle forwarded Windows Authentication, client certificates, etc..
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseIIS(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<IISMiddleware>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds middleware for interacting with the IIS AspNetCoreModule reverse proxy module.
|
||||
/// This will handle forwarded Windows Authentication, client certificates, etc..
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseIIS(this IApplicationBuilder app, IISOptions options)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<IISMiddleware>(Options.Create(options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// 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.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public class IISOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// If true the authentication middleware alter the request user coming in and respond to generic challenges.
|
||||
/// If false the authentication middleware will only provide identity and respond to challenges when explicitly indicated
|
||||
/// by the AuthenticationScheme.
|
||||
/// </summary>
|
||||
public bool AutomaticAuthentication { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true authentication middleware will try to authenticate using platform handler windows authentication
|
||||
/// If false authentication middleware won't be added
|
||||
/// </summary>
|
||||
public 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;
|
||||
|
||||
/// <summary>
|
||||
/// Additional information about the authentication type which is made available to the application.
|
||||
/// </summary>
|
||||
public IList<AuthenticationDescription> AuthenticationDescriptions { get; } = new List<AuthenticationDescription>()
|
||||
{
|
||||
new AuthenticationDescription()
|
||||
{
|
||||
AuthenticationScheme = IISDefaults.Negotiate
|
||||
},
|
||||
new AuthenticationDescription()
|
||||
{
|
||||
AuthenticationScheme = IISDefaults.Ntlm
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>8b3446e8-e6a8-4591-aa63-a95837c6e97c</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||
{
|
||||
internal class NativeMethods
|
||||
{
|
||||
#if DOTNET5_4
|
||||
private const string api_ms_win_core_handle_LIB = "api-ms-win-core-handle-l1-1-0.dll";
|
||||
#else
|
||||
private const string KERNEL32 = "kernel32.dll";
|
||||
#endif
|
||||
|
||||
#if DOTNET5_4
|
||||
[DllImport(api_ms_win_core_handle_LIB, ExactSpelling = true, SetLastError = true)]
|
||||
#else
|
||||
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
|
||||
#endif
|
||||
internal static extern bool CloseHandle(IntPtr handle);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// 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.Reflection;
|
||||
using System.Resources;
|
||||
|
||||
[assembly: AssemblyMetadata("Serviceable", "True")]
|
||||
[assembly: NeutralResourcesLanguage("en-us")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation.")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: AssemblyProduct("Microsoft ASP.NET Core")]
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"compilationOptions": {
|
||||
"warningsAsErrors": true,
|
||||
"keyFile": "../../tools/Key.snk",
|
||||
"nowarn": [ "CS1591" ],
|
||||
"xmlDoc": true
|
||||
},
|
||||
"description": "ASP.NET Core components for working with the IIS AspNetCoreModule.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/aspnet/IISIntegration"
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Hosting.Abstractions": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Http": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Http.Extensions": "1.0.0-*",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "1.0.0-*",
|
||||
"Microsoft.Extensions.Options": "1.0.0-*",
|
||||
"Microsoft.Extensions.SecurityHelper.Sources": {
|
||||
"type": "build",
|
||||
"version": "1.0.0-*"
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net451": { },
|
||||
"netstandard1.3": {
|
||||
"dependencies": {
|
||||
"System.Security.Principal.Windows": "4.0.0-*"
|
||||
},
|
||||
"imports": [ "dotnet5.4" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ using Microsoft.Extensions.Logging;
|
|||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
// Uses ports ranging 5061 - 5069.
|
||||
public class HelloWorldTests
|
||||
|
|
@ -77,6 +77,14 @@ namespace Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests
|
|||
try
|
||||
{
|
||||
Assert.Equal("Hello World", responseText);
|
||||
|
||||
response = await httpClient.GetAsync("/Path%3F%3F?query");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("/Path??", responseText);
|
||||
|
||||
response = await httpClient.GetAsync("/Query%3FPath?query?");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("?query?", responseText);
|
||||
}
|
||||
catch (XunitException)
|
||||
{
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class Helpers
|
||||
{
|
||||
|
|
@ -118,7 +118,7 @@
|
|||
</sectionGroup>
|
||||
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||
<section name="webSocket" overrideModeDefault="Deny" />
|
||||
<section name="httpPlatform" overrideModeDefault="Allow" />
|
||||
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
|
|
@ -253,7 +253,7 @@
|
|||
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
|
||||
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="httpPlatformHandler" image="%SystemRoot%\System32\inetsrv\httpPlatformHandler.dll" />
|
||||
<add name="AspNetCoreModule" image="%SystemRoot%\System32\inetsrv\aspnetcore.dll" />
|
||||
</globalModules>
|
||||
|
||||
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
|
||||
|
|
@ -928,7 +928,7 @@
|
|||
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler,runtimeVersionv2.0" />
|
||||
<add name="httpPlatformHandler" />
|
||||
<add name="AspNetCoreModule" />
|
||||
</modules>
|
||||
<handlers accessPolicy="Read, Script">
|
||||
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
|
||||
|
|
@ -118,7 +118,7 @@
|
|||
</sectionGroup>
|
||||
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||
<section name="webSocket" overrideModeDefault="Deny" />
|
||||
<section name="httpPlatform" overrideModeDefault="Allow" />
|
||||
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
|
|
@ -253,7 +253,7 @@
|
|||
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
|
||||
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="httpPlatformHandler" image="%SystemRoot%\system32\inetsrv\httpPlatformHandler.dll" />
|
||||
<add name="AspNetCoreModule" image="%SystemRoot%\system32\inetsrv\aspnetcore.dll" />
|
||||
</globalModules>
|
||||
|
||||
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
|
||||
|
|
@ -928,7 +928,7 @@
|
|||
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler,runtimeVersionv2.0" />
|
||||
<add name="httpPlatformHandler" />
|
||||
<add name="AspNetCoreModule" />
|
||||
</modules>
|
||||
<handlers accessPolicy="Read, Script">
|
||||
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
|
||||
|
|
@ -12,7 +12,7 @@ using Microsoft.Extensions.Logging;
|
|||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
// IisExpress preregisteres 44300-44399 ports.
|
||||
public class HttpsTest
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>a83a33d1-3d29-403c-9750-5811ac7b4025</ProjectGuid>
|
||||
<ProjectGuid>7f2f50c7-610f-4b69-b945-ca283511a587</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
|
@ -118,7 +118,7 @@
|
|||
</sectionGroup>
|
||||
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||
<section name="webSocket" overrideModeDefault="Deny" />
|
||||
<section name="httpPlatform" overrideModeDefault="Allow" />
|
||||
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
|
|
@ -253,7 +253,7 @@
|
|||
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
|
||||
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="httpPlatformHandler" image="%SystemRoot%\System32\inetsrv\httpPlatformHandler.dll" />
|
||||
<add name="AspNetCoreModule" image="%SystemRoot%\System32\inetsrv\aspnetcore.dll" />
|
||||
</globalModules>
|
||||
|
||||
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
|
||||
|
|
@ -928,7 +928,7 @@
|
|||
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler,runtimeVersionv2.0" />
|
||||
<add name="httpPlatformHandler" />
|
||||
<add name="AspNetCoreModule" />
|
||||
</modules>
|
||||
<handlers accessPolicy="Read, Script">
|
||||
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
|
||||
|
|
@ -12,7 +12,7 @@ using Microsoft.Extensions.Logging;
|
|||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.IISPlatformHandler.FunctionalTests
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
// Uses ports ranging 5050 - 5060.
|
||||
public class NtlmAuthenticationTests
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
"content": [
|
||||
"Http.config",
|
||||
"Https.config",
|
||||
"NtlmAuthentation.config",
|
||||
"NtlmAuthentation.config"
|
||||
],
|
||||
"compilationOptions": {
|
||||
"warningsAsErrors": true
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Builder;
|
||||
|
|
@ -9,10 +10,33 @@ using Microsoft.AspNetCore.Http.Features.Authentication;
|
|||
using Microsoft.AspNetCore.TestHost;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.IISPlatformHandler
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration
|
||||
{
|
||||
public class HttpPlatformHandlerMiddlewareTests
|
||||
public class IISMiddlewareTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task MiddlewareSkippedIfTokenIsMissing()
|
||||
{
|
||||
var assertsExecuted = false;
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(context =>
|
||||
{
|
||||
var auth = context.Features.Get<IHttpAuthenticationFeature>();
|
||||
Assert.Null(auth);
|
||||
assertsExecuted = true;
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, "");
|
||||
await server.CreateClient().SendAsync(req);
|
||||
Assert.True(assertsExecuted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddsAuthenticationHandlerByDefault()
|
||||
{
|
||||
|
|
@ -21,12 +45,18 @@ namespace Microsoft.AspNetCore.IISPlatformHandler
|
|||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseIISPlatformHandler();
|
||||
Environment.SetEnvironmentVariable("ASPNETCORE_TOKEN", "TestToken");
|
||||
app.Use((context, next) =>
|
||||
{
|
||||
context.Request.Headers["MS-ASPNETCORE-TOKEN"] = "TestToken";
|
||||
return next();
|
||||
});
|
||||
app.UseIIS();
|
||||
app.Run(context =>
|
||||
{
|
||||
var auth = (IHttpAuthenticationFeature)context.Features[typeof(IHttpAuthenticationFeature)];
|
||||
var auth = context.Features.Get<IHttpAuthenticationFeature>();
|
||||
Assert.NotNull(auth);
|
||||
Assert.Equal("Microsoft.AspNetCore.IISPlatformHandler.AuthenticationHandler", auth.Handler.GetType().FullName);
|
||||
Assert.Equal("Microsoft.AspNetCore.Server.IISIntegration.AuthenticationHandler", auth.Handler.GetType().FullName);
|
||||
assertsExecuted = true;
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
|
|
@ -47,13 +77,19 @@ namespace Microsoft.AspNetCore.IISPlatformHandler
|
|||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseIISPlatformHandler(new IISPlatformHandlerOptions
|
||||
Environment.SetEnvironmentVariable("ASPNETCORE_TOKEN", "TestToken");
|
||||
app.Use((context, next) =>
|
||||
{
|
||||
context.Request.Headers["MS-ASPNETCORE-TOKEN"] = "TestToken";
|
||||
return next();
|
||||
});
|
||||
app.UseIIS(new IISOptions
|
||||
{
|
||||
ForwardWindowsAuthentication = false
|
||||
});
|
||||
app.Run(context =>
|
||||
{
|
||||
var auth = (IHttpAuthenticationFeature)context.Features[typeof(IHttpAuthenticationFeature)];
|
||||
var auth = context.Features.Get<IHttpAuthenticationFeature>();
|
||||
Assert.Null(auth);
|
||||
assertsExecuted = true;
|
||||
return Task.FromResult(0);
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>fbbbe015-1ce3-454b-9647-23f8073fb7ab</ProjectGuid>
|
||||
<ProjectGuid>4106db10-e09f-480e-9ce6-b39235512ee6</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.IISPlatformHandler": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.TestHost": "1.0.0-*",
|
||||
"Microsoft.NETCore.Platforms": "1.0.1-*",
|
||||
"xunit": "2.1.0"
|
||||
|
|
@ -11,7 +11,7 @@ namespace TestSites
|
|||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseDefaultConfiguration(args)
|
||||
.UseIISPlatformHandlerUrl()
|
||||
.UseIISUrl()
|
||||
.UseStartup("TestSites")
|
||||
.UseServer("Microsoft.AspNetCore.Server.Kestrel")
|
||||
.Build();
|
||||
|
|
|
|||
|
|
@ -12,9 +12,18 @@ namespace TestSites
|
|||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole();
|
||||
app.UseIISPlatformHandler();
|
||||
app.UseIIS();
|
||||
app.Run(ctx =>
|
||||
{
|
||||
if (ctx.Request.Path.Value.StartsWith("/Path"))
|
||||
{
|
||||
return ctx.Response.WriteAsync(ctx.Request.Path.Value);
|
||||
}
|
||||
if (ctx.Request.Path.Value.StartsWith("/Query"))
|
||||
{
|
||||
return ctx.Response.WriteAsync(ctx.Request.QueryString.Value);
|
||||
}
|
||||
|
||||
return ctx.Response.WriteAsync("Hello World");
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace TestSites
|
|||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole();
|
||||
app.UseIISPlatformHandler();
|
||||
app.UseIIS();
|
||||
app.Run(ctx =>
|
||||
{
|
||||
if (ctx.Request.Path.Equals(new PathString("/checkclientcert")))
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ namespace TestSites
|
|||
}
|
||||
});
|
||||
|
||||
app.UseIISPlatformHandler();
|
||||
app.UseIIS();
|
||||
|
||||
app.Use((context, next) =>
|
||||
{
|
||||
if (context.Request.Path.Equals("/Anonymous"))
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
"wwwroot/**/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.IISPlatformHandler": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*",
|
||||
"Microsoft.AspNetCore.WebUtilities": "1.0.0-*",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-*",
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
<system.webServer>
|
||||
<!-- This repository cannot use the iis publish tool because there's a bug in the installer if the tool package is a package reference -->
|
||||
<!-- See https://github.com/dotnet/cli/issues/1215 -->
|
||||
<httpPlatform forwardWindowsAuthToken="true" processPath="..\TestSites.exe" stdoutLogEnabled="false" stdoutLogFile="..\logs\stdout.log" startupTimeLimit="3600" />
|
||||
<aspNetCore forwardWindowsAuthToken="true" processPath="..\TestSites.exe" stdoutLogEnabled="false" stdoutLogFile="..\logs\stdout.log" startupTimeLimit="3600" />
|
||||
<handlers>
|
||||
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
Loading…
Reference in New Issue