Faking Forms Authentication in Silverlight

15 בפברואר 2011

תגיות: , ,
אין תגובות

In a website that implements Forms Authentication Silverlight fits in very easily – Forms Authentication leaves a cookie on the client – and Silverlight just picks it off if you’re using the Browser Stack (which you normally would). In other words – It simply works.

However, many times you would like to do the authentication yourself – that is – to fake an HTTP Post so that you can authenticate to a server without having the user actually fill the form and submit it – you’d like to do it programmatically in Silverlight.

My first thought was doing the following:

   1: WebClient wc = new WebClient();

   2:  

   3: this.completed = Completed;

   4:  

   5: wc.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);

   6:  

   7: wc.UploadStringAsync(new Uri("http://MyServer/login", UriKind.Absolute),

   8:     String.Format("username={0}&password={1}", user, pass));

 

Using WebClient, we can call UploadStringAsync to upload a list of parameters (those usually would be the form fields – in this case it’s username and password), and thus fake the HTTP Post of the form.

It worked like a charm for a few hours, and then one of the programmers in the team started getting Access Denied from the server. It took me quite some time to realize why… (and a lot of fiddling with fiddler)

I took snapshots of the http activity on my computer and on the computer of the other programmer, only to find out the my computer was creating a slightly different web-request. It was adding content-type header:

content-type: application/x-www-form-urlencoded

 

Turns out that Chrome by default adds this header, whereas IE8 does not. Weird..

I’m pretty sure that IE is the one that’s correct. Chrome just added this header all by itself – It was supposed to be rejected because we have to add this ourselves.

All you need to do is to add the following line:

   1: wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";

and it works.

 

I’m actually not sure why the server is checking this, but in our case (Spring over Java over Apache) it was.

The full code looks like this:

   1: public class FormsAuthenticationHelper

   2: {

   3:     Action completed = null;

   4:  

   5:     public void Authenticate(string user, string pass, Action Completed)

   6:     {

   7:         WebClient wc = new WebClient();

   8:  

   9:         this.completed = Completed;

  10:  

  11:         wc.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);

  12:  

  13:         // hack for IE8. Chrome does this automatically

  14:         wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";

  15:  

  16:         wc.UploadStringAsync(new Uri("http://localhost:58289/login", UriKind.Absolute),

  17:             String.Format("j_username={0}&j_password={1}", user, pass));

  18:     }

  19:  

  20:     void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)

  21:     {

  22:         if (this.completed != null)

  23:             this.completed();

  24:  

  25:     }

  26:  

  27: }

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *