One of the things the Silverlight Networking stack lacks is the support for credentials. Where we have things like the below in the full CLR, Silverlight doesn't have any support.
httpWebRequest.Credentials = new NetworkCredential(username, password);
Investigation
So what about some investigation of the use of credentials. I remembered something about the usage of request headers for sending credentials. After a few minutes googleing I got support from a page on Oreilly about HTTP Headers. I found out the headername is "Authorization" and the value consist of authorization scheme and the credentials base64 encoded.
Tryout in full CLR
I tried to get it to work within the full CLR. I made two extension methods, one to set the RequestHeader and the other to convert a string to base64 encoding. As you can see the username and password will be divided by a colon before encoding the string to base64.
This code seemed to work on the CLR. So I thought very nice, on to the limited Silverlight CLR.
1 internal static class Extensions
2 {
3 public static void SetCredentials(this WebRequest request, string username, string password)
4 {
5 request.Headers["Authorization"] = string.Format("Basic {0}",
6 string.Format("{0}:{1}",username, password).EncodeTo64());
7 }
8
9 public static string EncodeTo64(this string toEncode)
10 {
11 byte[] toEncodeAsBytes
12 = Encoding.ASCII.GetBytes(toEncode);
13
14 string returnValue
15 = Convert.ToBase64String(toEncodeAsBytes);
16 return returnValue;
17 }
18 }
Trying to get it to work with the Silverlight CLR
The first thing I had to do was to change the Encoding to use Encoding.Unicode, the ASCII character set isn't available as it seems. After this all the compilation errors were gone. But something very frustrating came around: "Error: This header must be modified using the appropriate property." Was I doing something wrong? It worked on the full CLR, why not within Silverlight?
After an investigation with Reflector I found out about a line of code that checks if a header is supported. A few clicks further and there was the list of not allowed headers.
And this list sadly also contains the headername "Authorization". I also found out that the list of allowed headers has a length of 12 headers. But also new custom headers are supported. The lists below are read from doing some inspection with Reflector.
List of unsupported headers: Allow, Accept, Authorization, Accept-Charset, Accept-Encoding, Accept-Language, Cookie, Connection, Content-Type, Content-Range, Content-Length, Content-Location, Date, Expect, Host, Keep-Alive, Last-Modified, Max-Forwards, Proxy-Authorization, Range, Referer, TE, Trailer, Transfer-Encoding, Upgrade, User-Agent, Via, Warning, Allowed, Connect, Content-Transfer-Encoding, Delete, Get, Head, Options, Post, Proxy-Connection, Public, Put, Request-Range, Trace, Uri, X-Flash-Version, Accept-Ranges, Age, ETag, Location, Proxy-Authenticate, Retry-After, Server, Vary, WWW-Authenticate.
List of supported headers: Cache-Control, Content-Encoding, Content-Language, Content-MD5, Expires, From, If-Match, If-Range, If-None-Match, If-Modified-Since, If-Unmodified-Since, Pragma. Besides this also custom headers are supported.
I hope we get support for using credentials within requests as soon as possible. Almost all services on the web use some form of credentials don't they?