runtime: ASP.NET Core 2.1 impersonation WSALookupServiceEnd error
Setup: Client: IE or Chrome Server: Asp.Net Core 2.1 via IIS with Windows Auth enabled.
Scenario: A client logs into a web app using windows credentials. The web app in turn impersonates that user to make outgoing HTTP requests also using windows credentials.
Expected: The outgoing HTTP request should made using the impersonated user’s credentials.
Actual: A System.Net.WebException is thrown.
Sample code:
[ApiController]
[Route("[controller]/[action]")]
public class ImpersonationTestController : ControllerBase
{
private readonly ILogger<ImpersonationTestController> _logger;
public ImpersonationTestController(ILogger<ImpersonationTestController> logger)
{
_logger = logger;
}
[HttpGet]
public ActionResult Test()
{
try
{
return WindowsIdentity.RunImpersonated(((WindowsIdentity) User.Identity).AccessToken, () =>
{
var url = $"";
using (var client = new WebClient {UseDefaultCredentials = true})
using (var responseStream = client.OpenRead(url))
using (var reader = new StreamReader(responseStream))
{
var response = reader.ReadToEnd();
return Ok(response);
}
});
}
catch (Exception ex)
{
var message = "Impersonation Test Error!!";
_logger.LogError(ex, message);
return StatusCode(500, message);
}
}
}
Stack Trace:
System.Net.WebException: A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled ---> System.Net.Http.HttpRequestException: A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled ---> System.Net.Sockets.SocketException: A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at System.Net.HttpWebRequest.SendRequest()
at System.Net.HttpWebRequest.GetResponse()
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetResponse()
at System.Net.WebClient.GetWebResponse(WebRequest request)
at System.Net.WebClient.OpenRead(Uri address)
at System.Security.Principal.WindowsIdentity.<>c__DisplayClass60_0`1.<RunImpersonated>b__0()
at System.Security.Principal.WindowsIdentity.<>c__DisplayClass64_0.<RunImpersonatedInternal>b__0(Object <p0>)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Security.Principal.WindowsIdentity.RunImpersonatedInternal(SafeAccessTokenHandle token, Action action)
at System.Security.Principal.WindowsIdentity.RunImpersonated[T](SafeAccessTokenHandle safeAccessTokenHandle, Func`1 func)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (7 by maintainers)
In order to resolve this, we change the default value of Socket hander to false.
you can set environment variable <environmentVariable` name=“DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER” value=“0”> or AppContext.SetSwitch(“System.Net.Http.UseSocketsHttpHandler”, false);
The impersonated user does not have privilege to open socket in a local machine. that’s why application throws exception.