问题
I need to have my tests run as a testing account. To accomplish that I setup to the following code to create a handle into my testing account:
SafeAccessTokenHandle testAccountHandle;
bool returnValue = LogonUser("TestAccount", "myDom.net",
"pass", 2, 0, out testAccountHandle);
I can then make a call to load a URL:
HttpResponseMessage response = null;
await WindowsIdentity.RunImpersonated<Task>(testAccountHandle, async () =>
{
var url = "https://accounts.google.com/.well-known/openid-configuration";
response = await httpClient.GetAsync(url);
});
testAccountHandle.Dispose();
When I run this in a console application, it works just fine. (Likewise in LinqPad.)
However when I run this code in an NUnit test, I get the following error:
System.Net.Sockets.SocketException : This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server.
It says it is usually a temporary error, but it happens every single time I run impersonated in the NUnit Test, and never when I run in the Console. It also never happens when I run in the NUnit test if I am not running impersonated. (In short it ONLY happens when in an NUnit Test and Impersonated.)
I am not sure how to go about debugging this. It seems clear that NUnit does not like my impersonation, but I am not sure what to do about it.
How can I make a successful HttpClient.GetAsync
call while using RunImpersonated
in an NUnit test?
NOTE: Full repro code can be found here: https://github.com/nunit/nunit/issues/3672
回答1:
This appears to be a bug with .NET Core. See the open issue and discussion here: https://github.com/dotnet/runtime/issues/29935
It seems that WindowsIdentity.RunImpersonated() works differently in .NET Core compared with .NET Framework. This is causing a variety of issues including one affecting ASP.NET Core, #29351.
There is some difference in the way that the identity token permissions are getting set on the impersonated token. This is causing "access denied" issues in a variety of ways.
Workaround
Issue #29351 from ASP.NET Core references this exact error message and contains a workaround. Setting the environment variable DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER
to 0
disables the SocketsHttpHandler and makes this problem go away. For example, the following works without the error:
Environment.SetEnvironmentVariable("DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER", "0");
HttpResponseMessage response = null;
await WindowsIdentity.RunImpersonated<Task>(testAccountHandle, async () =>
{
var url = "https://accounts.google.com/.well-known/openid-configuration";
response = await httpClient.GetAsync(url);
});
You may need to make considerations for only setting this environment variable for this specific test and not for every test. I'm not sure what the impacts of disabling the SocketsHttpHandler are, so use the workaround at your own risk.
来源:https://stackoverflow.com/questions/64902793/using-runimpersonated-for-an-httpclient-call-fails-for-a-nunit-test-but-works-i