Home > English > Getting the user credentials both in and out of the browser in Silverlight

Getting the user credentials both in and out of the browser in Silverlight

Silverlight is quite powerful and gives you a lot of flexibility. You can have your application run in the browser our you can opt for a more Windows like experience and run your application Out of the Browser. One of the frustrations that I have encountered in the past, is trying to write my code so that it supports both.

A common scenario is trying to get the current user signed into the computer. With Silverlight running in the browser, this is quite easy by passing information into the InitParams. But this becomes quite a bit more difficult when you are trying to do the same Out of the Browser.

The following is a screen shot of retrieving the currently signed in user from a web page:

Current User - Browser

In discussing this issue with some colleagues of mine, it came to me that solving the problem for out of the browser could be quite simple if we allow for elevated priviledges. My solutions was to use COM Automation.

The following is the same application now running out of the browser displaying the currently signed in user:

Current User - Out Of Browser

In this post we will go through getting the currently signed in user from the hosting web page and then via COM.

We will start with the web page first. First of all, you need to have a web page that has code-behind associated with it. The default behavior of Visual Studio is to create an ASPX page without any code-behind. The following is a code snippet of the hosting web page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestComInterop.Web.Default" %>




    TestComInterop
    <!--
    html, body {
	    height: 100%;
	    overflow: auto;
    }
    body {
	    padding: 0;
	    margin: 0;
    }
    #silverlightControlHost {
	    height: 100%;
	    text-align:center;
    }
    
-->
    <script src="Silverlight.js" type="text/javascript"><!--mce:0--></script>
    <script type="text/javascript"><!--mce:1--></script>


<form id="form1" style="height: 100%;">
<div id="silverlightControlHost"></div>
</form>


I posted the whole in its entirety but there is only one element that you need to pay attention to with the ID=”InitParameters”. We will use this Literal tag to inject our current user from the code-behind.

Now let’s look at the code-behind:

public partial class Default : System.Web.UI.Page
{
	protected void Page_Load(object sender, EventArgs e)
	{
		Response.Cache.SetCacheability(HttpCacheability.NoCache);
		ConfigureSilverlightDeploymentSettings(InitParameters);
	}

	private static void ConfigureSilverlightSettings(Literal settings)
	{
		StringBuilder sb = new StringBuilder();
		sb.Append("<param name=\"InitParams\" value=\"");
		sb.Append("UserName");
		sb.Append("=");
		sb.Append(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
		sb.Append("\" />");
		settings.Text = sb.ToString();
	}
};

Basically, I am turning off caching in the Page_Load method as well as calling the ConfigureSilverlightSettings method. It is in this method that we dynamically construct a Param with the name of “InitParams”. This is the mechanism that Silverlight gains access to parameters we wish to pass to it externally. We then just create a key/value pair setting the UserName value to GetCurrent().Name property from System.Security.Principal.WindowsIdentity.

The last piece of this puzzle is to see how this is accessed from Silverlight. This leads us to the App.xaml.cs file. For brevity, I am only going to show you the Application_Startup method as it is the only thing that concerns us:

private void Application_Startup(object sender, StartupEventArgs e)
{
	this.RootVisual = new MainPage();

	if (Application.Current.IsRunningOutOfBrowser)
	{
		if (AutomationFactory.IsAvailable)
		{
			using (dynamic wScript = AutomationFactory.CreateObject("WScript.Network"))
			{
				this.UserName = string.Format(@"{0}\{1}", wScript.UserDomain, wScript.UserName);
			}
		}
	}
	else
	{
		// We are running in the browser and can use the HTML-Bridge to get our user.
		this.UserName = e.InitParams.ContainsKey("UserName") ? e.InitParams["UserName"] : "UNKNOWN";
	}

	Application.Current.Resources.Add("UserName", this.UserName);
}

I am showing you the solution for both but I want you to first focus on the else condition. Basically, we are just pulling the key/value pair from the InitParams object off of the StartupEventArgs object. I also ensure that we get a dummy value if no “UserName” exists as a key.

The final step is to add this to the Application.Current.Resources dictionary so that we can access it globally. You may have your own mechanism or may want to use your favorite DI/IOC container to handle this as well.

This really completes the web page workflow. Since we have the code for the App.xaml.cs file, let’s examine how this is accomplished out of the browser. If you look above, we are first checking to be sure that the application IsRunningOutOfBrowser. We also check to be sure that we have elevated priviledges to use COM Automation. Once this is established the we simply create a “WScript.Network” object. This allows us to use the Windows Script API and access the networking stack. Finally we format a string so that it looks just like what we would get from the web page.

The last piece of the puzzle is displaying the message box. The code-behind from the MaingPage.xaml file has the follwoing content:

public partial class MainPage : UserControl
{
	public MainPage()
	{
		InitializeComponent();
	}

	private void Button_Click(object sender, RoutedEventArgs e)
	{
		if (Application.Current.IsRunningOutOfBrowser)
		{
			MessageBox.Show(string.Format("OOB Current User: {0}", Application.Current.Resources["UserName"]));
		}
		else
		{
			MessageBox.Show(string.Format("Browser Current User: {0}", Application.Current.Resources["UserName"]));
		}
	}
};

I only added a condition test so that the screen shots would be different. The rest is just accessing the Resources property off of the Application.Current object. Again, you could do this quite differently using DI/IOC in your code.

I have zipped up a sample application to download here.

Hope this helps….

Advertisements
  1. kevin
    January 27, 2011 at 8:39 pm

    I wonder if I could use fiddler to change the init param (in the non-COM interop implementaion) then I can be anyone I want in the system. any thoughts?

  2. sam spurling
    June 27, 2011 at 3:26 pm

    Thanks very helpful

  3. September 24, 2011 at 7:39 am

    Hi, thanks for the example…
    How do I get the following user name and password?

  4. July 31, 2012 at 5:16 pm

    Nice. However, your examples in the screenshots do not 100% line up with your explanation. Downloading the sample helped out. I am speaking specifically to the aspx content page and the code behind.

    Otherwise, nice idea.

  5. August 12, 2013 at 6:06 am

    Vi norgesautomaten spill ser det klarest nettoppdette
    tidsrommet var det s leverer spillet det bruke den siste tiden du vi norgesautomaten spilll
    er svrt profesjonell.

  1. January 18, 2011 at 2:23 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: