Silverlight Twitter Client with authentication

Its not easy to access a cross domain RSS feed. But it is nearly impossible to do same with authentication. HTTP Client stack and HTTP browser stack in Silverlight 3 and beyond does not support authentication. All tricks with manipulating HTTP header throw some not implemented exception.

For my workaround I use a browser bridge built with Jscript.

First i created a twitter account and closed the RSS feed to “followers”. Which have the effect that when accessing the RSS with browser Login Dialog is poping up.

Next step is I add a AJAX Scriptmanager into the aspx page which is hosting Silverlight Plugin. Then i write the JScript code to  access the Twitter url. The magic is inside the HTTP Header. You have to implement “username:password” base64 encoded in authorization header tag. This sample creates from SilverlightInsi:password the base64 string. The encoding will be done later in Silverlight application.

function anmelden(user) {
//  base 64 =U2lsdmVybGlnaHRJbnNpOnBhc3N3b3Jk
    var w = new Sys.Net.WebRequest();
    w.set_url("http://twitter.com/statuses/friends_timeline/61248865.rss");
    w.set_httpVerb("GET");
    w.get_headers()["Authorization"] = "Basic " + user;
    w.add_completed(WennFertig);
    w.invoke();
}

Now we code a button click in silverlight. With htmlpage helper we can invoke the Jscript RSS download function “anmelden” and pass the security credentials.

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Dim user As String = "SilverlightInsi"
    Dim pwd As String = "password"
    Dim daten() As Byte = System.Text.Encoding.UTF8.GetBytes((user + ":" + pwd))
    HtmlPage.Window.Invoke("anmelden", Convert.ToBase64String(daten))

When the data have arrived, Jscript calls function “WennFertig” in ASPX page. There you get the response data (the rss). To bring back the data to Silverligth application we call a managed code function calles Twitterloaded. To get the reference you have to find the Plugin (ID of object). And take the content and use the “sl” object. We will see the why and how a few lines later

 function WennFertig(executor, eventArgs) {
      if (executor.get_responseAvailable()) {
         var SL = document.getElementById("sl1");
          SL.Content.sl.TwitterLoaded(executor.get_responseData());

       }
 }

Now we are back in manged code of Silverligth. I register the plug for Jscript as “sl”. This allows Jscript in general to access the insides of the plugin

 Public Sub New()
        InitializeComponent()
        HtmlPage.RegisterScriptableObject("sl", Me)

    End Sub

We need a managed function which can be called from outside by Jscript. That is declarted by ScriptableMember Attribut. So function “Twitterloaded” can now be invoked from outside. The next lines are quit tricky. I use the Syndication class from Silverlight. This saves a lot of coding, cause I d not need to creat data classes or extra lists.

<ScriptableMember()> _
Public Sub TwitterLoaded(ByVal daten As String)
        Dim sr As StringReader = New StringReader(daten)
        Dim xr As XmlReader = XmlReader.Create(sr)
        Dim feed As SyndicationFeed = SyndicationFeed.Load(xr)
       datagrid1.ItemsSource = feed.Items.ToList
End Sub

One issue is left. The SyndicationItem is not a flat datatype. So I have to take in care in XAML binding to refer to right property, like Title.Text. The datagrid gets templatecolumns.

  <data:DataGrid.Columns>
       <data:DataGridTemplateColumn Width="200">
             <data:DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                       <TextBlock Text="{Binding Title.Text}" />
                 </DataTemplate>
              </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
       <data:DataGridTemplateColumn Width="100">
             <data:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                       <TextBlock Text="{Binding PublishDate}" />
                </DataTemplate>
       </data:DataGridTemplateColumn.CellTemplate>
    </data:DataGridTemplateColumn>
</data:DataGrid.Columns>
 </data:DataGrid>

At the end my application looks like that.

image

Was hard work, I hope you enjoy it. If you want to learn more you can attend my classes at ppedv AG.

Published Thursday, July 30, 2009 3:00 PM by preishuber

Comments

# Silverlight Twitter Client with authentication - Hannes Preishuber

Pingback from  Silverlight Twitter Client with authentication - Hannes Preishuber

# Silverlight Twitter Client with authentication | Silverlight Travel

Pingback from  Silverlight Twitter Client with authentication  | Silverlight Travel

# re: Silverlight Twitter Client with authentication

Monday, August 03, 2009 7:59 AM by SilverGeek

Nice work! I didn't know you could do that.

Would you share the full source code? I am trying to reproduce it but it seems a bit tricky.

Thanks.

# re: Silverlight Twitter Client with authentication

Saturday, October 03, 2009 10:36 PM by Daní

I'm getting an "acces denied" error

# re: Silverlight Twitter Client with authentication

Thursday, October 08, 2009 8:36 PM by saavedrah

Great work, however when I tried it worked perfect in IE but in  Firefox and Chrome it just get the UnAuthenticated (401) response from the server

# re: Silverlight Twitter Client with authentication

Tuesday, December 22, 2009 7:05 PM by brian o'neil

Any work around for an out of browser application?

Leave a Comment

(required) 
(required) 
(optional)
(required)