Sunday, April 17, 2011

Working with User Names and Roles in Silverlight Applications

Security is a key component of applications and something that developers often struggle with to get right. How do you authenticate a user? How do you integrate roles and use them to show or hide different parts of a screen? These and other questions commonly come up as I talk with developers working on ASP.NET and Silverlight applications.
I was recently presenting a workshop on Silverlight at the DevConnections conference in Orlando and had a question from the audience on how I handle security roles in Silverlight applications. Since I had just implemented a security mechanism for a customer I gave a brief response but didn’t have a sample application available to share to point people in the right direction. After the workshop was over I put together a sample application to demonstrate one potential approach for accessing user names and roles. I’ll walk through the sample application in this post and highlight the key components.
The goal of the post isn’t to dictate how to authenticate users since every application has unique requirements. However, I will discuss general techniques for accessing user names and working with roles to block access to views and show or hide controls.
Security Techniques
Silverlight applications can take advantage of Windows and Forms authentication techniques and can integrate user roles into the mix as well. However, unless you use WCF RIA Services on the backend you’ll need to write the plumbing code to authenticate a user if you need to do it directly within the application. WCF RIA Services projects provide login and registration screens out of the box that leverage Forms authentication by default. You can view a walk-through of the WCF RIA Services authentication process here http://msdn.microsoft.com/en-us/library/ee942449(VS.91).aspx.
WCF RIA Services also provides a means for accessing an authenticated user’s user name and roles by using a WebContext object (see http://msdn.microsoft.com/en-us/library/ee707361(VS.91).aspx). This isn’t possible out-of-the-box in a standard Silverlight application unless you write custom code to handle it. If WCF RIA Services is appropriate for your project then it’s a great way to go for data exchange and security tasks. If you won’t be using WCF RIA Services then this post will provide insight into other techniques that can be used.
Most of the Silverlight Line of Business (LOB) applications I’ve worked on authenticate the user at the page level using Windows authentication. If the user can’t authenticate into the page then the Silverlight application is never displayed. With out-of-browser applications the Windows user account can be passed through and accessed as calls to a service are made. The sample application available with this post assumes that authentication occurs at the page level as opposed to within the Silverlight application itself.

Accessing a User’s Identity
To access an authenticated user’s user name within a Silverlight application you can either pass the user name into the object tag’s initialization parameter (called “initParams”) or call a service that returns the user name. An example of passing in the user name using the initParams option within an ASP.NET page that is hosting the object tag is shown next:

<param name="initParams" value="UserName=<%=User.Identity.Name%>" />
Within App.xaml.cs you can access the initParams parameters and store them. The code below shows how to do this and add initParams values into the application resources so that they can be accessed throughout the application.
private void Application_Startup(object sender, StartupEventArgs e)
{
    ProcessInitParams(e.InitParams);
    this.RootVisual = new MainPage();
}
private void ProcessInitParams(IDictionary<string, string> initParams)
{
    if (initParams != null)
    {
        foreach (var item in initParams)
        {
            this.Resources.Add(item.Key, item.Value);
        }
    }
}