My WebApi client project is loosing the WindowsIdentity of the current user when executing SendAsync Method from HttpClient.
HttpContext.User returns the application pool identity. Not the impersonated WindowsIdentity.
The client project is .NET Standard, so it can be used in .NET Framework and .NET Core.
When using RestSharp all works without problems and ExecutionContext.SuppressFlow() is not needed. (I can´t use RestSharp because the clients are generated by NSwag.)
.NET Framework:
When using ExecutionContext.SuppressFlow() the Identity will be correctly delegating to the server.
.NET Core:
When using .NET 7 following exception will be thrown:
Cannot call Set on a null context
Exception:
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Security.Principal.WindowsIdentity.RunImpersonatedInternal(SafeAccessTokenHandle token, Action action)
at System.Security.Principal.WindowsIdentity.GetName()
at System.Net.Http.CurrentUserIdentityProvider.GetIdentity()
at System.Net.Http.HttpConnectionPoolManager.GetConnectionKey(HttpRequestMessage request, Uri proxyUri, Boolean isProxyConnect)
at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(HttpRequestMessage request, Uri proxyUri, Boolean async, Boolean doRequestAuth, Boolean isProxyConnect, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPoolManager.SendAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.HttpAuthenticatedConnectionHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpMessageHandlerStage.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext()
at System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext()
Minimal code snippet:
UriBuilder uriBuilder = new()
{
Scheme = Uri.UriSchemeHttps,
Host = "localhost",
Port = 7042
};
var urlBuilder = new StringBuilder();
urlBuilder.Append(uriBuilder.ToString() + "/WeatherForecast");
HttpClientHandler handler = new()
{
UseDefaultCredentials = true,
PreAuthenticate = true
};
HttpClient client = new(handler);
using var request = new HttpRequestMessage();
request.Method = new HttpMethod("GET");
var url = urlBuilder.ToString();
request.RequestUri = new Uri(url, UriKind.RelativeOrAbsolute);
ExecutionContext.SuppressFlow();
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
Does the ExcecutionContext need to be used differently in .NET Core?