HttpClient 호출에 RunImpersonated를 사용하면 NUnit 테스트에 실패하지만 콘솔에서 작동합니다.

Nov 18 2020

테스트 계정으로 테스트를 실행해야합니다. 이를 수행하기 위해 다음 코드를 설정하여 테스트 계정에 대한 핸들을 만듭니다.

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();

콘솔 응용 프로그램에서 이것을 실행하면 잘 작동합니다. (LinqPad에서도 마찬가지입니다.)

그러나 NUnit 테스트에서이 코드를 실행하면 다음 오류가 발생합니다.

System.Net.Sockets.SocketException : 이것은 일반적으로 호스트 이름 확인 중 일시적인 오류이며 로컬 서버가 권한있는 서버로부터 응답을받지 못했음을 의미합니다.

일반적으로 일시적인 오류라고 말하지만 NUnit 테스트에서 가장 한 실행을 실행할 때마다 발생하며 콘솔에서 실행할 때는 발생하지 않습니다. 가장을 실행하지 않으면 NUnit 테스트를 실행할 때도 발생하지 않습니다. (요컨대 NUnit 테스트에서 가장 된 경우에만 발생합니다.)

이것을 디버깅하는 방법을 잘 모르겠습니다. NUnit이 내 명의 도용을 좋아하지 않는 것 같지만 어떻게해야할지 모르겠습니다.

NUnit 테스트에서 HttpClient.GetAsync사용하는 동안 어떻게 성공적인 호출을 할 수 RunImpersonated있습니까?

참고 : 전체 재현 코드는 여기에서 찾을 수 있습니다. https://github.com/nunit/nunit/issues/3672

답변

2 kylejrp Nov 24 2020 at 01:05

이것은 .NET Core의 버그로 보입니다. 여기에서 열린 문제 및 토론을 참조하십시오.https://github.com/dotnet/runtime/issues/29935

WindowsIdentity.RunImpersonated ()는 .NET Framework와 비교하여 .NET Core에서 다르게 작동하는 것 같습니다. 이로 인해 ASP.NET Core에 영향을 미치는 문제, # 29351을 비롯한 다양한 문제가 발생합니다.

가장 된 토큰에 ID 토큰 권한이 설정되는 방식에는 약간의 차이가 있습니다. 이로 인해 다양한 방식으로 "액세스 거부"문제가 발생합니다.

해결 방법

ASP.NET Core의 문제 # 29351 은이 정확한 오류 메시지를 참조하고 해결 방법을 포함합니다. 환경 변수 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER를 설정하여 0SocketsHttpHandler 를 비활성화하고이 문제를 해결합니다. 예를 들어 다음은 오류없이 작동합니다.

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);
});

모든 테스트가 아닌이 특정 테스트에 대해서만이 환경 변수를 설정하는 것을 고려해야 할 수 있습니다. SocketsHttpHandler 비활성화의 영향이 무엇인지 확실하지 않으므로 해결 방법을 사용하여 위험을 감수하십시오.