1

Perhaps I'm missing something, or perhaps .NET is missing something (preferably the former)

When building an application (not exclusively ASP.NET, but such is my situation; specifically an ASP.NET hosted WCF DS) it seems there's no native way to create a NetworkCredential object from an HttpRequest, or any similar request/header container,.

Do we always have to roll our own, or is there some magic tucked away in System.Net.* or System.Web.* with a signature like:

NetworkCredential GetAuthorization(HttpRequest request);

It's trivial I know, but I would assume something standard to the HTTP architecture would be included in something that is otherwise so encompassing (.NET)

So, home-brew string manipulation, or magic method hiding somewhere?

Dan Lugg
  • 20,192
  • 19
  • 110
  • 174
  • Is there a reason you specifically want or need a `NetworkCredential`? Why are `User` (and equivalents) not adequate? – Damien_The_Unbeliever Feb 12 '13 at 18:43
  • I'm referring to the fact that in most forms of ASP.Net (WebForms, MVC, Web API) there's a convenient `User` property that gives you a more fully featured object (usually implementing `IPrincipal` or `IIdentity`) that offers many features that are convenient. What features, specific to `NetworkCredential` are you wanting to use? – Damien_The_Unbeliever Feb 12 '13 at 18:51
  • (*I was confused with my last comment*) `NetworkCredential` is not an absolute requirement, but is fitting; even the description mentions Basic, Digest, etc. – Dan Lugg Feb 12 '13 at 18:51
  • I'm not currently working with WebForms, MVC, or Web API; instead ASP.NET hosting WCF Data Services. I have access to `HttpRequest`, etc., and assumed that there would/should be a way to obtain a generic credentials object (*`NetworkCredential`*) from somewhere given a supplied HTTP Authorization header. There isn't anything specific about `NetworkCredential` that's necessary. I'm just wondering if .NET has provided us some way of obtaining a generic credentials object based on Basic HTTP Authorization, or if I'm stuck rolling my own. – Dan Lugg Feb 12 '13 at 18:55

1 Answers1

1

I don't think there's anything built-in; it would be of limited use, since most clients use Kerberos or Digest authentication instead.

However, it's fairly simple to roll your own:

static NetworkCredential ParseBasicAuthorizationHeader(string value)
{
   if (string.IsNullOrWhiteSpace(value)) 
   {
      return null;
   }
   if (!value.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase)) 
   {
      return null;
   }

   byte[] data = Convert.FromBase64String(value.Substring(6));
   value = Encoding.GetEncoding("ISO-8859-1").GetString(data);

   int index = value.IndexOf(':');
   if (index == -1 || index == 0 || index == value.Length - 1) 
   {
      return null;
   }

   return new NetworkCredential(
      value.Substring(0, index),    // Username
      value.Substring(index + 1));  // Password
}

Bear in mind that, like all other HTTP headers, the Authorization header is completely controlled by the client, and should therefore be treated as untrusted user input.

Richard Deeming
  • 29,830
  • 10
  • 79
  • 151
  • Thanks @RichardDeeming; I was afraid of that. Simplicity aside, I'm a bit surprised that there isn't support for Basic floating around .NET. In any case, +1 for bringing `ISO-8859-1` to my attention, I'm using something else (*`ASCII` I think*) – Dan Lugg Feb 12 '13 at 19:40
  • @Bracketworks: I found the encoding in [this SO answer](http://stackoverflow.com/a/7243567/124386); the spec seems to be unclear on this point, but most implementations seem to use `ISO-8859-1`. – Richard Deeming Feb 12 '13 at 19:47
  • Awesome, thanks. I'm going to leave this here a bit longer, in the event someone stumbles in with a magic bullet from .NET, however discussion of this has the answer looking grim (*though in your favor*) – Dan Lugg Feb 12 '13 at 22:09