Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing username and password to .NET HttpWebRequest via URI does not work

Running the following code:

var request = HttpWebRequest.Create("http://username:[email protected]/test-http-status-codes.asp?code=401");
var response = request.GetResponse();

... and inspecting the request using Wireshark reveals that no authorization is attempted by my client (the url is a simple service that will always return 401).

This code sends an authorization header after the initial challenge:

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

Using the System.Uri class has no effect. Why is the username and password passed in the url not used for authentication?

(I'm aware of this blog post on passing the authorization header without an initial challenge, but that is not the issue at hand)

EDIT I should add that it is fairly easy to work around this limitation, for example with this bit of code (add url un-escaping to taste), I'm just curious as to why you have to do this:

var userInfo = request.Address.UserInfo;
if (!string.IsNullOrEmpty(userInfo) && userInfo.Contains(':'))
{
    request.Credentials = new NetworkCredential(userInfo.Split(':').First(), userInfo.Split(':').Last());
}
like image 259
friism Avatar asked Nov 09 '11 00:11

friism


1 Answers

The HttpWebRequest class does not utilize the credentials in the Uri (per dotPeek).

But the FtpWebRequest does, here is the relevant code:

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

As you can see it just attaches it to credentials, so you should just do that instead manually with a parsed Uri

like image 92
Paul Tyng Avatar answered Nov 10 '22 13:11

Paul Tyng