Home > Programming, Silverlight > Silverlight 4 Windows Authentication

Silverlight 4 Windows Authentication


Today I’m going to talk to you about two simple ways to enable windows authentication in your Silverlight 4 apps.

Source code: here

1. First of all, you’ll need to create a new Silverlight application project in VS2010

2. Add a new item -> Silverlight-enabled WCF service. Named mine AuthenticationService.

3. In the Web project Add a reference to System.DirectoryServices (Method 1 – you can use since .NET 2.0) and one to System.DirectoryServices.AccountManagement (Method 2 – usable since .NET 3.5). Correct me if I’m wrong on the version availability.

4. Paste the following code in AuthenticationService.svc.cs:

   [OperationContract]
public bool AuthenticationMethod1(string user, string pass)
   {
bool valid = false;
try
     {
        DirectorySearcher ds = new DirectorySearcher(new DirectoryEntry("LDAP://yourdomain", user, pass));
        ds.Filter = String.Format("(SAMAccountName={0})", user);
ds.PropertiesToLoad.Add("SAMAccountName");
SearchResult result = ds.FindOne();
valid = result != null;
}
catch (COMException)
{
        //wrong pass or expired pass
        valid = false;
}
return valid;
}

[OperationContract]
public bool AuthenticationMethod2(string user, string pass)
{
PrincipalContext context = new PrincipalContext(ContextType.Domain, "yourdomain");
bool valid = context.ValidateCredentials(user, pass);
UserPrincipal usr = UserPrincipal.FindByIdentity(context, user);
return valid;
   }

5. Add a service reference from the Silverlight app to the newly added service.

6. Paste the following code in the MainPage.xaml.cs:

private AuthService.AuthenticationServiceClient proxy = new AuthService.AuthenticationServiceClient();

public MainPage()
{
InitializeComponent();
proxy.AuthenticationMethod1Completed += new EventHandler<AuthService.AuthenticationMethod1CompletedEventArgs>(proxy_AuthenticationMethod1Completed);
proxy.AuthenticationMethod2Completed += new EventHandler<AuthService.AuthenticationMethod2CompletedEventArgs>(proxy_AuthenticationMethod2Completed);
}

private void btnLogin1_Click(object sender, RoutedEventArgs e)
{
proxy.AuthenticationMethod1Async(txtUsername.Text, txtPassword.Password);
}

private void proxy_AuthenticationMethod1Completed(object sender, AuthService.AuthenticationMethod1CompletedEventArgs e)
{
if (e.Error == null)
{
MessageBox.Show(e.Result ? "Logged in 1!" : "Login 1 failed!");
}
}

private void btnLogin2_Click(object sender, RoutedEventArgs e)
{
proxy.AuthenticationMethod2Async(txtUsername.Text, txtPassword.Password);
}

private void proxy_AuthenticationMethod2Completed(object sender, AuthService.AuthenticationMethod2CompletedEventArgs e)
{
if (e.Error == null)
{
MessageBox.Show(e.Result ? "Logged in 2!" : "Login 2 failed!");
}
}

7. Finally, paste the xaml in the MainPage.xaml:

<Grid x:Name="LayoutRoot" Background="White">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Background="LightBlue">
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Text="Username" HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Grid.Row="1" x:Name="txtUsername" Margin="5,0,0,0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" />
<TextBlock Grid.Row="2" Text="Password" HorizontalAlignment="Right" VerticalAlignment="Center" />
<PasswordBox x:Name="txtPassword" Margin="5,0,0,0" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" />
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"
Grid.ColumnSpan="2">
<Button x:Name="btnLogin1" Click="btnLogin1_Click" Content="Login Method 1" />
<Button x:Name="btnLogin2" Margin="5,0,0,0" Click="btnLogin2_Click" Content="Login Method 2" />
</StackPanel>
</Grid>
</Grid>

Well that’s all for the coding part folks!

Method 1 is using the DirectorySearcher object which allows us to search within the Active Directory for a specific user and load data about him by calling the FindOne method.

Method 2 is using the PrincipalContext object to connect to the Active Directory and calls the ValidateCredentials method. Also, calling the static FindByIdentity method on UserPrincipal within the given context returns a UserPrincipal instance containing lots of interesting stuff related to that user: AccountExpirationDate, EmailAddress, Description, DisplayName, Groups, Name etc.

I personally like Method 2 as it’s shorter and more clear in terms of understanding. But if you need extra muscle power you can always dig into the Active Directory and do some pretty interesting queries with Method 1.

Happy coding! 😉

AuthenticateMethod1
Advertisements
  1. carlos
    05/10/2011 at 9:04 am

    Excellent Post

  2. 26/11/2011 at 9:22 pm

    This looks good but I can’t find the AuthService namespace. Can you help me out. Thanks, fb

    • 26/11/2011 at 9:27 pm

      My bad. I got it. I’m a newbie. 🙂

  3. 26/11/2011 at 9:52 pm

    Method 1 works for me. method two does not. using context of domain i get ‘bad username or password’. Using machine context with a known domain controller, I get access denied.

    I tried my domain as hws.edu and hwsmicro (th original domain name). Any ideas?

    Thanks, fb

  1. 02/01/2011 at 2:12 pm

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: