C# 对HttpClient调用使用RunImpersonated对于NUnit测试失败,但可以在控制台中工作

C# 对HttpClient调用使用RunImpersonated对于NUnit测试失败,但可以在控制台中工作,c#,.net-core,nunit,impersonation,.net-core-3.1,C#,.net Core,Nunit,Impersonation,.net Core 3.1,我需要让我的测试作为测试帐户运行。为了实现这一点,我设置了以下代码,以便在我的测试帐户中创建句柄: SafeAccessTokenHandle testAccountHandle; bool returnValue = LogonUser("TestAccount", "myDom.net", "pass", 2, 0, out testAccountHandle); 然后我可以调用以加载URL: HttpRespo

我需要让我的测试作为测试帐户运行。为了实现这一点,我设置了以下代码,以便在我的测试帐户中创建句柄:

SafeAccessTokenHandle testAccountHandle;

bool returnValue = LogonUser("TestAccount", "myDom.net", 
       "pass", 2, 0, out testAccountHandle);
然后我可以调用以加载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();
httpresponsemessageresponse=null;
等待WindowsIdentity.RunImpersonated(testAccountHandle,异步()=>
{
变量url=”https://accounts.google.com/.well-known/openid-configuration";
response=wait-httpClient.GetAsync(url);
});
testAccountHandle.Dispose();
当我在控制台应用程序中运行它时,它工作得很好。(LinqPad也是如此。)

但是,当我在NUnit测试中运行此代码时,会出现以下错误:

System.Net.Sockets.SocketException:这通常是主机名解析过程中的临时错误,意味着本地服务器没有收到来自权威服务器的响应

它说这通常是一个临时错误,但每次我在NUnit测试中运行模拟时都会发生,在控制台中运行时就不会发生。如果我没有模拟运行,在NUnit测试中运行时也不会发生这种情况。(简而言之,只有在NUnit测试和模拟中才会发生这种情况。)

我不知道如何调试这个。很明显,努尼特不喜欢我的模仿,但我不知道该怎么办

在NUnit测试中使用
RunImpersonated
时,如何成功调用
HttpClient.GetAsync


注意:完整的复制代码可以在这里找到:

这似乎是一个.NET核心的错误。请参见此处的公开问题和讨论:

与.NET Framework相比,WindowsIdentity.RunImpersonated()在.NET内核中的工作方式似乎有所不同。这导致了各种问题,包括一个影响ASP.NET核心的问题#29351

在模拟令牌上设置标识令牌权限的方式上存在一些差异。这以多种方式造成了“拒绝访问”问题

变通办法 引用此错误消息并包含解决方法。将环境变量
DOTNET\u SYSTEM\u NET\u HTTP\u USESOCKETSHTTPHANDLER
设置为
0
将禁用SocketsHttpHandler并消除此问题。例如,以下操作不会出现错误:

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);
});
Environment.SetEnvironmentVariable(“DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER”,“0”);
HttpResponseMessage响应=null;
等待WindowsIdentity.RunImpersonated(testAccountHandle,异步()=>
{
变量url=”https://accounts.google.com/.well-known/openid-configuration";
response=wait-httpClient.GetAsync(url);
});

您可能需要考虑仅为此特定测试而不是每个测试设置此环境变量。我不确定禁用SocketsHttpHandler会有什么影响,因此使用此解决方案的风险由您自己承担。

如果您以测试用户身份登录并打开浏览器,您是否能够成功访问url,或者是否会出现错误?作为测试用户在accounts.google.com上运行nslookup怎么样?我只是想确认你的网络没有问题configuration@kylejrp-当以测试用户身份登录时,我能够访问URL。另外,如果不在NUnit测试中运行(但仍然以测试用户的身份在代码中运行),它运行得很好。这可能与您声明的
httpClient
的上下文有关吗?看起来您将其声明在
RunImpersonated
的范围之外,我想知道这是否会影响
HttpClient
使用的用户。这是瞎猜,但如果您在模拟范围内声明
httpClient
,该怎么办?@kylejrp-听起来很有希望,但我刚刚尝试过,但还是失败了。@kylejrp-我在NUnit GitHub网站上发布了这篇文章:如果您感兴趣,我在那里发布了完整的复制。谢谢您的回答!我接受这一点作为答案,但我想补充一点(对于未来的读者),即此设置已在.NET5.0中删除。因此,此解决方案仅适用于.Net Core。