407需要验证 - 未发送任何挑战

时间:2009-09-18 10:10:14

标签: c# proxy httpwebrequest http-status-code-407

更新
如果您刚刚提到这个问题,那么一般的要点是我正在尝试通过代理进行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)需要身份验证。

正在使用的代理

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

System.Net跟踪输出

IE成功协商代理

解决方案

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

8 个答案:

答案 0 :(得分:8)

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

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

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

(Fiddler的“Auth”检查员将为您分解NTLM身份验证blob,如果您尚未查看它。)

答案 1 :(得分:6)

我编写了一个实用程序来解码在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位安全性已成为默认值,如果没有,则身份验证将失败。从服务器响应中可以看出,服务器仅支持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位加密。

希望这有帮助。

答案 2 :(得分:3)

答案 3 :(得分:1)

secpol.msc中验证以下设置。它解决了我们的问题。

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

设为:

require 128 only for client. 

enter image description here

答案 4 :(得分:0)

您可以尝试将HttpWebRequest上的User-Agent标头设置为与IE8设置的值相同吗?

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

希望这会有所帮助。

答案 5 :(得分:0)

是代理分配的方式吗?

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中配置代理

<system.net>
  <defaultProxy enabled="true">
    <proxy
      autoDetect="False"
      bypassonlocal="True"
      scriptLocation="http://www.proxy.pac"
      proxyaddress="http://proxy1.blah.com" />
  </defaultProxy>
</system.net>

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

这个怎么样:

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