407需要validation – 未发送任何挑战

更新:
如果您刚刚提到这个问题,那么一般的要点是我正在尝试通过代理创建一个HttpWebRequest,并且我从我们奇怪的代理服务器获得了407。 IE,Firefox,Chrome都能成功地协商代理,Adobe Air应用程序也是如此。 Google Chrome网络安装程序实际上失败并且我们必须使用离线安装程序可能很重要。

感谢Ian的链接,我已经让它进入​​下一阶段。 它现在将令牌发送回代理,但是第3阶段没有通过,因此具有用户名/密码哈希的请求不是由.NET发送的,因此不返回HTML。

我在用:

  • IE6用户代理
  • Windows 7的
  • 扫描安全代理
  • .NET 3.5

这是最新的代码,相当于下面的日志:

HttpWebRequest request = HttpWebRequest.Create("http://www.yahoo.com") as HttpWebRequest; IWebProxy proxy = request.Proxy; // Print the Proxy Url to the console. if (proxy != null) { // Use the default credentials of the logged on user. proxy.Credentials = CredentialCache.DefaultCredentials; } request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"; request.Accept = "*/*"; HttpWebResponse response = request.GetResponse() as HttpWebResponse; Stream stream = response.GetResponseStream(); 

例外

WebException(407)需要身份validation。

正在使用的代理

代理客户端是我们服务器机房中的Scansafe硬件设备,它(一旦通过NTLM进行身份validation),然后将您的HTTP流量定向到其服务器以过滤流量。

System.Net跟踪输出

  • 这是跟踪输出

IE成功地协商代理

  • Fidder输出

解决方案

我还没有真正找到解决方案但是感谢Feroze和Eric我找到了一个解决方法并发现实际的代理(而不是它的配置)是主要问题。 这可能是一个模糊的问题,有3个变量:.NET HttpWebRequest的实现,Windows 7,当然还有位于我们机架中的Scansafe硬件客户端; 但没有MSDN支持请求我不会发现。

如果要为代理设置凭据,是否应该在request.Proxy对象而不是请求对象上设置凭据?

http://msdn.microsoft.com/en-us/library/system.net.webproxy.credentials.aspx

此外,请记住,您需要发出HTTP / 1.1请求(或技术上,任何使用Keep-Alive的请求)才能成功使用NTLM / Negotiate身份validation。

(Fiddler的“Auth”检查员会为你分解NTLM认证blob,如果你还没有看过那个。)

我编写了一个实用程序来解码在IE和HttpWebRequest会话中发送的NTLM blob。

当我查看HttpWebRequest和IE时,他们都从服务器请求56位和128位加密。 这是使用HttpWebRequest的会话转储

 ==== Type1 ---- Signature: NTLMSSP Type: 1 Flags: E20882B7 NTLMSSP_NEGOTIATE_56 NTLMSSP_NEGOTIATE_KEY_EXCH NTLMSSP_NEGOTIATE_128 RESERVED2 RESERVED3 RESERVED4 NTLMSSP_REQUEST_NON_NT_SESSION_KEY NTLMSSP_TARGET_TYPE_DOMAIN NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED NTLMSSP_NEGOTIATE_DATAGRAM NTLMSSP_REQUEST_TARGET NTLM_NEGOTIATE_OEM NTLMSSP_NEGOTIATE_UNICODE) Domain : Workstation: ==== Type2 ---- Signature: NTLMSSP Type: 2 Flags: 201 NTLMSSP_NEGOTIATE_56 NTLMSSP_REQUEST_NON_NT_SESSION_KEY) Context: D32FDDCB:63507CFA 

这是来自IE的转储:

 ==== Type1 ---- Signature: NTLMSSP Type: 1 Flags: A208B207 NTLMSSP_NEGOTIATE_56 NTLMSSP_NEGOTIATE_KEY_EXCH NTLMSSP_NEGOTIATE_128 NTLMSSP_REQUEST_NON_NT_SESSION_KEY NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY NTLMSSP_TARGET_TYPE_SHARE NTLMSSP_TARGET_TYPE_DOMAIN NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED NTLMSSP_NEGOTIATE_DATAGRAM NTLMSSP_REQUEST_TARGET NTLMSSP_NEGOTIATE_UNICODE) Domain : XXXX.UK Workstation: XXX-X31 ==== Type2 ---- Signature: NTLMSSP Type: 2 Flags: 201 NTLMSSP_NEGOTIATE_56 NTLMSSP_REQUEST_NON_NT_SESSION_KEY) Context: D32FDDCB:63507CFA 

在IE / HttpWebRequest中,它们都要求64和128位安全性。 但是,对于Windows7,NTLM的128位安全性已成为默认值,如果没有,则身份validation将失败。 从服务器响应中可以看出,服务器仅支持64位加密。

以下链接讨论了另一个人遇到的类似问题。 http://social.msdn.microsoft.com/Forums/en-US/ncl/thread/f68e8878-53e9-4208-b589-9dbedf851198

IE工作的原因,而不是托管应用程序,是IE实际上不请求NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN,最终需要加密。 但是,HttpWebRequest确实请求SEAL | SIGN。 这需要128位加密,而IE初始化NTLMSSP(没有SEAL&SIGN)的方式,它不需要加密。 因此IE工作,而HttpWebRequest则没有。 (见上面的链接)

我认为,如果您更改安全策略以允许NTLM的64位加密,您的托管代码应用程序将起作用。 或者,请求代理供应商支持NTLM的128位加密。

希望这可以帮助。

validationsecpol.msc的以下设置。 它解决了我们的问题。

 Local Security Policy Local Policies Security Options Network security: Minimum session security 

调成:

 require 128 only for client. 

在此处输入图像描述

您可以尝试在HttpWebRequest上设置User-Agent标头,使其与IE8设置的值相同吗?

有时,如果用户代理不是他们期望的,服务器将不会正确地挑战。

希望这可以帮助。

这是代理分配的方式吗?

 proxy.Credentials = CredentialCache.DefaultCredentials; 

当我上次使用HttpWebRequest的代理时,它被分配如下:

将代理分配给请求:

 request.Proxy.Credentials = Credentials.GetProxyCredentials(); 

通话方式:

  public static ICredentials GetProxyCredentials() { return new NetworkCredential(AppConstants.Proxy_username, AppConstants.Proxy_password); } 

在web.config中配置代理

      

它可能与您的“CredentialCache”中的内容有关。 试试这个:

 proxy.Credentials = new NetworkCredential("username", "pwd", "domain"); 

这个怎么样:

  HttpWebRequest request = HttpWebRequest.Create("http://www.yahoo.com") as HttpWebRequest; WebProxy proxyObject = new System.Net.WebProxy("http://10.0.0.1:8080/", true); //whatever your proxy address is proxyObject.Credentials = CredentialCache.DefaultCredentials; request.Proxy = proxyObject; request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"; request.Accept = "*/*"; HttpWebResponse response = request.GetResponse() as HttpWebResponse; Stream stream = response.GetResponseStream();