7

I'm trying to do impersonation in a .NET Core 2.1 Web-API. So this Web-API calls another Web-API using HttpClient and I need the user that called the first one to also be the one who is executing the second one. The same scenario does work from another Web-API running with the full framework with this call:

((WindowsIdentity)_httpContextAccessor.HttpContext.User.Identity).Impersonate()

Since Impersonate() is not available in .NET Core 2.1 I searched for some samples with WindowsIdentity.RunImpersonated and tried different versions of code similar to this:

WindowsIdentity identity = (WindowsIdentity)m_contextAccessor.HttpContext.User.Identity;
HttpClient client = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true });

await WindowsIdentity.RunImpersonated(identity.AccessToken, async () =>
{
    var request = new HttpRequestMessage(HttpMethod.Get, url);
    var response = await client.SendAsync(request);
});

This throws an error at client.SendAsync and the error message is this:

A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled ---> System.Net.Http.HttpRequestException

Start of the Stack Trace:

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)

Has anyone else seen this error or has any insight on how to solve this? I tried different versions of code for calling RunImpersonated with the HttpContext user and all lead to the same error.

Thanks for any input

Igor Cova
  • 3,126
  • 4
  • 31
  • 57
Beachovic
  • 81
  • 4

3 Answers3

3

Starting with .NET Core 2.1, the SocketsHttpHandler class provides the implementation used by higher-level HTTP networking classes such as HttpClient. try to disable this feature and see if the exception is gone.

  • This might very well solve the problem, because "The impersonated user does not have privilege to open socket in a local machine. that's why application throws exception." Switch off with this command: AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false); – Johan Danforth Mar 27 '20 at 12:43
1
await WindowsIdentity.RunImpersonated(identity.AccessToken, async () =>
{
    //this should give you the impersonated user
    var impersonatedUser = WindowsIdentity.GetCurrent().Name;

    var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true });
    var request = new HttpRequestMessage(HttpMethod.Get, url);
    var response = await client.SendAsync(request);
});
AD.Net
  • 13,352
  • 2
  • 28
  • 47
0

Even though this error is super vague, I'm pretty sure that this issue is related to the server refusing to connect to the endpoint, OR it can't find the endpoint. My issue was that the endpoint was not visible by the webserver - and FYI, don't use "localhost:xxxx" to point to a local port. Instead, use the server full IP address in your config. localhost doesn't always resolve in local DNS.

TLDR: make sure your webserver can ping the endpoint server and port with authority.

Christopher Bales
  • 1,069
  • 1
  • 13
  • 23