通过URI将用户名和密码传递给.NET HttpWebRequest不起作用

时间:2011-11-09 00:59:22

标签: .net http httpwebrequest uri

运行以下代码:

var request = HttpWebRequest.Create("http://username:password@savanttools.com/test-http-status-codes.asp?code=401");
var response = request.GetResponse();

...并使用Wireshark检查请求显示我的客户端未尝试授权(url是一个总是返回401的简单服务)。

此代码在初始质询后发送授权标头:

var request = HttpWebRequest.Create("http://username:password@savanttools.com/test-http-status-codes.asp?code=401");
request.Credentials = new NetworkCredential("username", "password");
var response = request.GetResponse();

使用System.Uri类无效。为什么在url中传递的用户名和密码不用于身份验证?

(我知道this blog post在没有初始质询的情况下传递授权标头,但这不是手头的问题)

编辑我应该补充一点,解决这个限制是相当容易的,例如使用这段代码(添加url un-escaping to taste),我只是好奇为什么你必须这样做:

var userInfo = request.Address.UserInfo;
if (!string.IsNullOrEmpty(userInfo) && userInfo.Contains(':'))
{
    request.Credentials = new NetworkCredential(userInfo.Split(':').First(), userInfo.Split(':').Last());
}

1 个答案:

答案 0 :(得分:3)

HttpWebRequest类不使用Uri(每个dotPeek)中的凭据。

FtpWebRequest确实如此,这是相关代码:

if (this.m_Uri.UserInfo != null && this.m_Uri.UserInfo.Length != 0)
  {
    string userInfo = this.m_Uri.UserInfo;
    string userName = userInfo;
    string password = "";
    int length = userInfo.IndexOf(':');
    if (length != -1)
    {
      userName = Uri.UnescapeDataString(userInfo.Substring(0, length));
      int startIndex = length + 1;
      password = Uri.UnescapeDataString(userInfo.Substring(startIndex, userInfo.Length - startIndex));
    }
    networkCredential = new NetworkCredential(userName, password);
  }

正如您所看到的,它只是将其附加到凭据,因此您应该使用已解析的Uri

手动执行此操作