System.Net.WebClient与代理身份验证407错误

12

我正在尝试强化使用System.Net.WebClient类时处理代理身份验证错误(HTTP 407状态代码)的方法。

在实际操作中,我们经常看到许多用户收到407代理身份验证WebException,但我不确定一个好的默认策略是什么。在 .Net 2.0/3.5 中,代理身份验证设置应该从Internet Explorer系统设置继承。Firefox、Opera和Chrome也使用这些相同的设置。

这是我们正在使用的基本代码:

using System.Net;

string url = "http://www.mysite.com";
WebClient webClient = new WebClient();
byte[] data = webClient.DownloadFile(url);

当这段代码失败时,我们会打开用户浏览器并将其发送到帮助页面。根据我们的网络日志,我们知道这些客户可以在浏览器中成功连接。也许他们在进入我们的帮助页面之前手动输入了代理用户名和密码?我们不知道。

看起来我们可以使用WebClient.UseDefaultCredentials,但是如果WebClient已经使用系统设置,这似乎是多余的。

任何帮助都感激不尽。

3个回答

11

如果代理身份验证使用BASIC或DIGEST,则Internet Explorer不会持久缓存/重用代理身份验证凭据。对于Negotiate / NTLM,默认凭据将被提供。

因此,即使.NET继承自IE设置,你也不会在Basic / Digest的代理身份验证方面获得任何“免费”支持,除非你正在运行IE;否则,你需要提示用户或提供一个配置屏幕。

Fiddler(www.fiddler2.com)在Rules菜单上有"Request Proxy Authentication"选项,可以用来模拟此场景进行测试。


2
谢谢Eric。Fiddler工作得很好。为了澄清一下,对于Negotiate/NTML,无论我是否设置UseDefaultCredentials=true,WebClient是否会提供默认凭据?换句话说,处理407 WebException并重试时,使用UseDefaultCredentials=true有价值吗?为什么不总是设置UseDefaultCredentials=true?安全风险吗?免责声明:WinInet似乎处理得更好。鉴于宇宙中的每个人都想要遍历代理,为什么不自动执行此操作或触发事件,并提供一个标准的用户界面来输入/保存凭据? - Daniel
我更多地尝试了Fiddler。我以为只需像下面这样提供用户名和密码(“1”,“1”)就很容易,但它不起作用。 string url = "http://www.java.com/"; webClient = new WebClient(); CredentialCache cache = new CredentialCache(); cache.Add(new Uri(url), "Basic", new NetworkCredential("1", "1")); webClient.Proxy.Credentials = credentialCache; webClient.Credentials = credentialCache; string contents = webClient.DownloadString(url); - Daniel
1
搞定了。由于某些原因,凭据缓存未能正常工作。我不得不将 NetworkCredential 传递给 webClient.Proxy.Credentials。 - Daniel

6

我知道这是一个旧帖子,但我遇到了类似的问题,尝试在SSIS 2008R2(SQL Server Integration Services)脚本任务(VB.NET代码)中使用WebClient下载XML文件,通过代理服务器连接到需要身份验证的SSL保护的远程站点。

花费了一些时间才找到解决方案,本帖在代理方面有所帮助。以下是对我有效的脚本代码。对于寻找类似解决方案的人可能会有用。

    Dim objWebClient As WebClient = New WebClient()
    Dim objCache As New CredentialCache()

    'https://www.company.net/xxxx/resources/flt
    Dim strDownloadURL As String = Dts.Variables("FileURL").Value.ToString

    'apiaccount@company.net
    Dim strLogin As String = Dts.Variables("FileLogin").Value.ToString

    'sitepassword
    Dim strPass As String = Dts.Variables("FilePass").Value.ToString

    'itwsproxy.mycompany.com
    Dim strProxyURL As String = Dts.Variables("WebProxyURL").Value.ToString

    '8080
    Dim intProxyPort As Integer = Dts.Variables("WebProxyPort").Value

    'Set Proxy & Credentials as a Network Domain User acc to get through the Proxy
    Dim wp As WebProxy = New WebProxy(strProxyURL, intProxyPort)
    wp.Credentials = New NetworkCredential("userlogin", "password", "domain")
    objWebClient.Proxy = wp

    'Set the Credentials for the Remote Server not the Network Proxy
    objCache.Add(New Uri(strDownloadURL), "Basic", New NetworkCredential(strLogin, strPass))
    objWebClient.Credentials = objCache

    'Download file, use Flat File Connectionstring to save the file
    objWebClient.DownloadFile(strDownloadURL, Dts.Connections("XMLFile").ConnectionString)

6
我们通过添加配置对话框来解决了这个问题,用户可以选择“使用代理”。 如果设置完成,我们将使用这些参数(地址、凭据等)。 如果没有设置 - 我们假设可以进行连接而无需任何手动交互。 在出现错误的情况下,我们会: a.) 使用默认凭证再次尝试 b.) 弹出一个信息提示,在配置中设置可能有所帮助...
如果代理身份验证是通过“默认凭证”(Windows用户)完成的,则IE也会对身份验证错误作出反应,并在此情况下发送默认凭证。 如果这不起作用,它会打开凭据对话框。 我不确定所有浏览器是否都是这样处理的 - 但是您可以使用fiddler进行简单测试,以便查看发生了什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接