我是否可以在不等待401挑战的情况下使HttpWebRequest包含Windows凭据?

Mat*_*hew 13 .net c# authentication httpwebrequest

我的应用程序与需要身份验证的内部Web API进行通信.

当我发送请求时,我按预期获得401质询,发生握手,重新发送经过身份验证的请求,一切都继续正常.

但是,我知道 auth是必需的.为什么我要等待挑战?我可以强制请求在第一个请求中发送凭据吗?

我的请求生成是这样的:

   private static HttpWebRequest BuildRequest(string url, string methodType)
   {
       var request = HttpWebRequest.CreateHttp(url);
       request.PreAuthenticate = true;
       request.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
       request.Credentials = CredentialCache.DefaultNetworkCredentials;
       request.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
       request.ContentType = CONTENT_TYPE;
       request.Method = methodType;
       request.UserAgent = BuildUserAgent();
       return request;
   }
Run Code Online (Sandbox Code Playgroud)

即使使用此代码,auth标头也不包含在初始请求中.

我知道如何将auth信息包含在基本....我想要做的是使用执行应用程序的用户的Windows Auth(所以我不能将密码存储在配置文件中).

更新我还尝试使用a HttpClient和它自己的.Credentials属性,结果相同:没有auth头添加到初始请求.

我可以获得auth标头的唯一方法是使用基本身份验证手动破解它(在这种情况下不会飞行)

小智 8

Ntlm是基于挑战/响应的认证协议.您需要发出第一个请求,以便服务器可以发出质询,然后在后续请求中客户端将响应发送给质询.然后,服务器通过向域控制器提供质询和客户端发送的响应来验证此响应.在不知道挑战的情况下,您无法发送响应,这就是为什么需要2个请求.

基本身份验证是基于密码的,因此您可以通过发送带有第一个请求的凭据来使其短路,但根据我的经验,这可能是某些服务器要处理的问题.

更多详细信息,请访问:http: //msdn.microsoft.com/en-us/library/windows/desktop/aa378749(v = vs.85).aspx


Ste*_*rne 6

我不是百分百肯定,但我怀疑没有办法解决这个问题; 这只是HttpWebRequest工作方式.

网上.NET源,功能DoSubmitRequestProcessing在这里,你可以在功能启动后看到此评论,线路1731:

        // We have a response of some sort, see if we need to resubmit
        // it do to authentication, redirection or something
        // else, then handle clearing out state and draining out old response.
Run Code Online (Sandbox Code Playgroud)

稍微向下(第1795行)(为简洁起见删除了一些行)

if (resubmit)
{   
   if (CacheProtocol != null && _HttpResponse != null) CacheProtocol.Reset();
   ClearRequestForResubmit(ntlmFollowupRequest);
   ...
}
Run Code Online (Sandbox Code Playgroud)

ClearRequestForResubmit第5891行:

// We're uploading and need to resubmit for Authentication or Redirect.
Run Code Online (Sandbox Code Playgroud)

然后(第5923行):

// The second NTLM request is required to use the same connection, don't close it
     if (ntlmFollowupRequest) {....}
Run Code Online (Sandbox Code Playgroud)

对于我(当然是n00bish)的眼睛,这些评论似乎表明开发人员决定遵循NTML/Kerberos的"标准"质询 - 响应协议,而不包括任何预先发送身份验证标头的方法.