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)

Most upvoted comments

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.