我'm building an application in an environment that'配置了Kerberos身份验证 . 我的应用程序使用.NET的 HttpClient
将一些数据发送到另一台服务器上的IIS中托管的API . GET请求似乎工作正常,但对同一服务的POST会立即崩溃,但会出现以下异常:
System.Net.Http.HttpRequestException:将内容复制到流时出错 . ---> System.IO.IOException:读取操作失败,请参阅内部异常 . ---> System.Net.WebException:请求已中止:请求已取消 . 在System.Net.ConnectStream.BeginRead(Byte []缓冲区,Int32偏移量,Int32大小,AsyncCallback回调,对象状态)在System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte []缓冲区,Int32偏移量,Int32计数, AsyncCallback回调,对象状态)---内部异常堆栈跟踪的结束---在系统的System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte []缓冲区,Int32偏移量,Int32计数,AsyncCallback回调,对象状态) .Net.Http.StreamToStreamCopy.StartRead()
我尝试使用Fiddler查看请求,根据我的理解,它会注入一个用于查看HTTP请求的HTTP代理 . 使用Fiddler时,我的POST请求成功 .
这是我看到的:
-
请求1导致
401 Unauthorized
. 当我检查请求标头时,没有Authorization
. 响应标头包含WWW-Authenticate: Negotiate
和WWW-Authenticate: NTLM
. -
请求2也会产生
401 Unauthorized
. 这次,它发送带有请求的Authorization: Negotiate YIGeBgYrBgEFBGQKgg (...)
标头 . 响应标头现在返回WWW-Authenticate: Negotiate oRUwE6A (...)
. -
请求3再次导致
401 Unauthorized
. 它随请求发送一个新的Authorization: Negotiate oTMwMaADCg (...)
标头,并获得带有响应的新WWW-Authenticate: Negotiate oYIBCzCCAQe (...)
标头 . -
请求4最终导致
200 OK
,带有预期的响应体 . 它在请求中还有一个Authorization: Negotiate oYICRzCCAkOg (...)
标头,响应中还有另一个WWW-Authenticate: Negotiate oRswGaADCg (...)
.
这似乎与我理解的Kerberos消息流相匹配 - 第一个请求是匿名尝试的,并获得需要身份验证的回复 . 第二个请求要求提供API服务器的票证,然后将其传递给Kerberos控制器,该控制器再次返回票证和客户/服务器使用的密钥 . 第三个请求直接进入API服务器以验证它们都可以使用票证,服务器确认这一点 . 第四个请求使用票证,一切都很顺利 .
但是,使用Fiddler作为服务器上的某些ghetto-proxy并不是一个可行的选择 . 所以,我的问题:
我怎么能在我的代码中处理这个?我的 HttpClient
将 PreAuthenticate
和 UseDefaultCredentials
都设置为true, WindowsIdentity.GetCurrent()
使用正确的域名返回我的用户 . 但是,它似乎什么都不做 . 没有Fiddler,我无法看到HTTP请求,但我认为它只是尝试第一个请求并在失败后自杀 . 我是否必须应用一些自定义代理才能使其正常工作?或者它应该开箱即用?