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

时间:2014-06-03 17:29:19

标签: c# .net authentication httpwebrequest

我的应用与需要身份验证的内部网络API进行通信。

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

但是,我知道需要使用身份验证。为什么我要等待挑战?我可以强制请求在第一个请求中发送凭据吗?

我的请求生成是这样的:

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

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

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

更新我还尝试使用HttpClient及其自己的.Credentials属性,但结果相同:初始请求中没有添加auth标头。

我可以获取auth标头的唯一方式是使用基本身份验证手动破解它(在此用例中不会飞行)

3 个答案:

答案 0 :(得分:8)

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

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

此处提供更多详细信息: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378749(v=vs.85).aspx

答案 1 :(得分:6)

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

online .NET source,函数DoSubmitRequestProcessing here中,您可以在函数开始后的第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.

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

if (resubmit)
{   
   if (CacheProtocol != null && _HttpResponse != null) CacheProtocol.Reset();
   ClearRequestForResubmit(ntlmFollowupRequest);
   ...
}

ClearRequestForResubmit第5891行:

// We're uploading and need to resubmit for Authentication or Redirect.

然后(第5923行):

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

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

答案 2 :(得分:2)

设置PreAuthenticate就是您想要的,您正在做的事情。第一个请求仍将执行握手,但对于后续请求,它将自动发送凭据(基于所使用的URL)。您可以在此处阅读:http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.preauthenticate(v=vs.110).aspx