(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

Cookies in Silverlight Web Requests

(2 votes)
Nikolay Raychev
>
Nikolay Raychev
Joined Mar 28, 2008
Articles:   22
Comments:   58
More Articles
5 comments   /   posted on Jun 18, 2008
Categories:   General

Introduction

When you are making a web request from a Silverlight application the cookies associated with the current browser-server session are automatically sent within each request.

A common scenario is when you have a web site with some kind of a cookie driven authentication implemented and a Silverlight application within your web site that shows different content depending on whether the user is logged in or not. The Silverlight application may use some resources on the server, which are accessible only to authenticated users. The good thing is that if you are logged in the web site and make requests from the Silverlight application the server “knows” that your requests come from an authenticated user. You do not need to login both on the web site and the Silverlight application.

Example

I made a simple example to test if all this stuff really works. I just want to have a simple web site with Form authentication and a Silverlight application which uses a resource from the server. The resource behaves differently when the user is logged in and when not. I won’t describe how I created the web site and the authentication system because you are not limited about the server technology. Currently it is ASP.NET web site with the standard ASP.NET membership. But you can also make it with PHP for example.

Provided my web site and the membership system are ready I create my resource. It is a plain text file which contains "Logged In" if the user is authenticated and "Anonymous" if not. I just create a generic handler with the following content:

<%@ WebHandler Language="C#" Class="IsAuthenticated" %>
 
using System;
using System.Web;
using System.Web.Security;
 
public class IsAuthenticated : IHttpHandler
{
    #region Properties
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
    #endregion
 
    #region Methods
    public void ProcessRequest (HttpContext context)
    {
        context.Response.ContentType = "text/plain";
 
        if ( Membership.GetUser( false ) != null )
        {
            context.Response.Write( "Logged In" );
        }
        else
        {
            context.Response.Write( "Anonumous" );
        }
    }
    #endregion
}

The only thing which I do is to try to get the current user and send different content to the browser depending on whether the current user exists or not. So my resource is ready.

Here is the Silverlight Implementation:

XAML:

<UserControl x:Class="SilverlightChat.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBlock x:Name="tblTest" Text="not loaded yet" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
    </Grid>
</UserControl>

I have only one TextBlock which shows my resource content or possible error information.

Code Behind:

using System;
using System.Net;
using System.Windows.Controls;
using System.IO;
using System.Text;
using System.Threading;
using System.Collections.ObjectModel;
 
namespace SilverlightChat
{
    public partial class Page : UserControl
    {
        private SynchronizationContext currentContext;
        private const string RESOURCE_URL = "your resource URL here";
 
        public Page()
        {
            InitializeComponent();
 
            this.currentContext = SynchronizationContext.Current;
            try
            {
                HttpWebRequest request = ( HttpWebRequest )WebRequest.Create( new Uri( RESOURCE_URL ) );
                request.BeginGetResponse( new AsyncCallback( this.RespCallback ), request );
            }
            catch ( Exception ex )
            {
                this.tblTest.Text = ex.Message;
            }
        }
 
        private void RespCallback( IAsyncResult result )
        {
            HttpWebRequest request = result.AsyncState as HttpWebRequest;
            try
            {
                using ( HttpWebResponse response = ( HttpWebResponse )request.EndGetResponse( result ) )
                {
                    if ( response.StatusCode == HttpStatusCode.OK )
                    {
                        Stream responseStream = response.GetResponseStream();
                        using ( responseStream )
                        {
                            StreamReader readStream = new StreamReader( responseStream, Encoding.UTF8 );
                            using ( readStream )
                            {
                                this.currentContext.Post( this.SetText, readStream.ReadToEnd() );
                            }
                        }
                    }
                    else
                    {
                        this.currentContext.Post( this.SetText, response.StatusCode.ToString() );
                    }
                }
            }
            catch ( Exception ex )
            {
                this.currentContext.Post( this.SetText, ex.Message );
            }
        }
 
        private void SetText( object state )
        {
            this.tblTest.Text = state as string;
        }
    }
}

I use the HttpWebRequest async methods to retrieve the resource from the server and set the Text of my TextBlock to the resource content. I handle the possible exceptions and if an exception occurs the text will contain the exception message. Also if the server returns status different from OK the text will contain the status code.

I tested my example with Fiddler to see if some cookies would be sent to the server. Only when the user was authenticated a cookie named “Login” was sent. Additionally my TextBlock showed the expected result.

Note that this will work only if your site membership system is cookie driven.

Your resource can be a web service or whatever you want.

Conclusion

This article focuses on the fact that you do not need to make login system both on your site and the Silverlight application when your site uses cookies for its authentication. Any comments are welcome.

Reference

I recommend you to read this article by Karen Corby where she explains the vulnerabilities that may originate from using cookie driven authentication and cross – domain requests from your Silverlight application.

http://scorbs.com/2008/04/22/silverlight-http-networking-stack-part-3-configuring-a-cross-domain-policy-file/

Since I did not make cross-domain requests in my example these things don’t bother me.


Subscribe

Comments

  • -_-

    RE: Cookies in Silverlight Web Requests


    posted by Ozzy on Jul 12, 2008 14:49

    I really liked your article because it is very clear and speaks directly to the problem I am having.

    My SL project calls a WCF service on my server. When I am authenticated, I can see that I am logged in using the same technique mentioned in your article.

    I also have an HTTP Handler in the same project on the same server, which contains code similar to your example; however, the MembershipUser is always null. Can you think of any reasons why this might be so? Is there something that needs to be entered into the web.config file?

  • nikolayraychev

    RE: Cookies in Silverlight Web Requests


    posted by nikolayraychev on Jul 14, 2008 00:32

    Thanks for your comment, Ozzy,

    Since things connected to Membership are not Silverlight specific it's better not to write about them here. You can send me an email on  nraychev [ at ] completit.com and I'll try to help you.

  • -_-

    RE: Cookies in Silverlight Web Requests


    posted by Maciej Gren on Jul 18, 2008 15:37

    Hi,

    First of all, thanks for nice article. I have a little bit more complicated example...

    I have ASPX page where I run my authentication mechanism which calls a external service. I receive from this service a very long token. Now I have to configure somehow the FormAuthentication cookie (I use ASP.Net Forms Authentication WCF Service with custom Membership, Role and Profile providers) to inform my own Authentication Service about positive login. But this is not visible to my Silverlight application where I have again to login.....

    How I should create that FormAuthentication cookie in my ASPX page (after receiving answer from my external auth. service) to enable my Silverlight application to be automatically logged in?

    Thanks in advance for help

  • -_-

    RE: Cookies in Silverlight Web Requests


    posted by drdamour on Oct 21, 2010 00:38

    i'm pretty sure this is no longer true in silverlight 4 if you read http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(VS.95).aspx you'll see a note about "for security reasons cookies are disabled by default".  however if you use the WebClient class, the cookies appear.

  • AjaySaksena

    Re: Cookies in Silverlight Web Requests


    posted by AjaySaksena on Aug 31, 2011 14:13

    Hello

Add Comment

Login to comment:
  *      *