Since we are developing a product, we need to support both Windows authentication (for most installations), and Forms Authentication for smaller installations or cases where the customer does not use Active Directory for whatever reason. A design goal we had for this was to only change the needed configuration in one place, and that ended up being the authentication tag in web.config. The solution turned out to be simple. What we did was to use initParams of the Silverlight host to set the configured value:
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<…>
<param name="initParams" value="authenticationMode=<%=
(int)((System.Web.Configuration.AuthenticationSection)System.Configuration.ConfigurationManager.GetSection("system.web/authentication")).Mode %>" />
</object>
When the application starts we sets up the WebContext depending on configured value of the authenitcation mode:
private void InitializeWebContext()
{
const int Windows = 1;
const int Forms = 3;
// Create a WebContext and add it to the ApplicationLifetimeObjects
// collection. This will then be available as WebContext.Current.
WebContext webContext = new WebContext();
int authenticationMethod =
Host.InitParams.ContainsKey("authenticationMode") ? int.Parse(this.Host.InitParams["authenticationMethod"], CultureInfo.InvariantCulture) : Windows;
if (authenticationMethod == Windows)
webContext.Authentication = new WindowsAuthentication();
else if (authenticationMethod == Forms)
{
webContext.Authentication = new FormsAuthentication();
}
else
throw new NotSupportedException();
this.ApplicationLifetimeObjects.Add(webContext);
// This will enable you to bind controls in XAML files to WebContext.Current
// properties
this.Resources.Add("WebContext", WebContext.Current);
}
In both cases we load the user when our main page is created.
WebContext.Current.Authentication.LoadUser(UserLoaded, null);
This will succeed if Windows Authentication is used or if the user have chosen “Remember Me” feature of the Forms Authentication. If the user isn’t loaded and Forms Authentication is configured, we then shows a login dialog prompting for user name and password. After closing it we call UserLoaded again so that our event UserAuthenticated is executed.
private void UserLoaded()
{
if (!WebContext.Current.User.IsAuthenticated && WebContext.Current.Authentication is FormsAuthentication)
{
LoginView loginWindow = new LoginView();
loginWindow.Closed += delegate(object sender, EventArgs e) { if (loginWindow.DialogResult == true) UserLoaded(); };
loginWindow.Show();
}
else if (WebContext.Current.User.IsAuthenticated)
{
OnUserAuthenticated(EventArgs.Empty);
}
}