Skip to content

Commit c13def5

Browse files
committed
Use ImpersonationToken for IIS Windows Auth
1 parent 9afcb72 commit c13def5

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ http_get_authentication_information(
513513
)
514514
{
515515
*pstrAuthType = SysAllocString(pInProcessHandler->QueryHttpContext()->GetUser()->GetAuthenticationType());
516-
*pvToken = pInProcessHandler->QueryHttpContext()->GetUser()->GetPrimaryToken();
516+
*pvToken = pInProcessHandler->QueryHttpContext()->GetUser()->GetImpersonationToken();
517517

518518
return S_OK;
519519
}

src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,11 +815,12 @@ FORWARDING_HANDLER::GetHeaders(
815815
(_wcsicmp(m_pW3Context->GetUser()->GetAuthenticationType(), L"negotiate") == 0 ||
816816
_wcsicmp(m_pW3Context->GetUser()->GetAuthenticationType(), L"ntlm") == 0))
817817
{
818-
if (m_pW3Context->GetUser()->GetPrimaryToken() != NULL &&
819-
m_pW3Context->GetUser()->GetPrimaryToken() != INVALID_HANDLE_VALUE)
818+
HANDLE impersonationToken = m_pW3Context->GetUser()->GetImpersonationToken();
819+
if (impersonationToken != NULL &&
820+
impersonationToken != INVALID_HANDLE_VALUE)
820821
{
821822
HANDLE hTargetTokenHandle = NULL;
822-
RETURN_IF_FAILED(pServerProcess->SetWindowsAuthToken(m_pW3Context->GetUser()->GetPrimaryToken(),
823+
RETURN_IF_FAILED(pServerProcess->SetWindowsAuthToken(impersonationToken,
823824
&hTargetTokenHandle));
824825

825826
//

src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/RequiresIISAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public RequiresIISAttribute(IISCapability capabilities)
136136
IsMet &= available;
137137
if (!available)
138138
{
139-
SkipReason += $"The machine does have {module.Capability} available.";
139+
SkipReason += $"The machine does not have {module.Capability} available.";
140140
}
141141
}
142142
}

src/Servers/IIS/IIS/test/Common.FunctionalTests/WindowsAuthTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Net;
56
using System.Net.Http;
7+
using System.Security.Principal;
68
using System.Threading.Tasks;
79
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
810
using Microsoft.AspNetCore.Server.IntegrationTesting;
@@ -58,4 +60,51 @@ public async Task WindowsAuthTest(TestVariant variant)
5860
Assert.StartsWith("Windows:", responseText);
5961
Assert.Contains(Environment.UserName, responseText);
6062
}
63+
64+
[ConditionalTheory]
65+
[RequiresIIS(IISCapability.WindowsAuthentication)]
66+
[MemberData(nameof(TestVariants))]
67+
public async Task WindowsAuthWithImpersonationLevelTest(TestVariant variant)
68+
{
69+
var deploymentParameters = Fixture.GetBaseDeploymentParameters(variant);
70+
deploymentParameters.SetAnonymousAuth(enabled: false);
71+
deploymentParameters.SetWindowsAuth();
72+
73+
// The default in hosting sets windows auth to true.
74+
var deploymentResult = await DeployAsync(deploymentParameters);
75+
76+
var impersonationLevels = new TokenImpersonationLevel[]
77+
{
78+
TokenImpersonationLevel.None,
79+
TokenImpersonationLevel.Identification,
80+
TokenImpersonationLevel.Impersonation,
81+
TokenImpersonationLevel.Delegation,
82+
TokenImpersonationLevel.Anonymous
83+
};
84+
85+
foreach (var impersonationLevel in impersonationLevels)
86+
{
87+
// TokenImpersonationLevel is not supported by HttpClient so we need to use HttpWebRequest to test it.
88+
#pragma warning disable SYSLIB0014 // Type or member is obsolete
89+
var request = HttpWebRequest.CreateHttp($"{deploymentResult.HttpClient.BaseAddress}Auth");
90+
#pragma warning restore SYSLIB0014 // Type or member is obsolete
91+
request.ImpersonationLevel = impersonationLevel;
92+
request.Method = "GET";
93+
request.UseDefaultCredentials = true;
94+
95+
using var response = request.GetResponse();
96+
using var reader = new StreamReader(response.GetResponseStream());
97+
var responseText = await reader.ReadToEndAsync();
98+
99+
try
100+
{
101+
Assert.StartsWith("Windows:", responseText);
102+
Assert.Contains(Environment.UserName, responseText);
103+
}
104+
catch (Exception ex)
105+
{
106+
Assert.Fail($"'TokenImpersonationLevel.{impersonationLevel}' failed with: {ex.Message}");
107+
}
108+
}
109+
}
61110
}

0 commit comments

Comments
 (0)