13 May 2010

Creating a security token service website using WIF in Visual Studio

This walk-though explains how to create a test claims issuer in Visual Studio using the Windows Identity Foundation SDK. This will allow you to set up and test claims-aware applications. This required the following to be installed on your machine before you get started:

  • The Windows Identity Foundation SDK, which can be installed from here.
  • Windows 7, Windows Vista SP2 or Windows Server 2008 R2
  • IIS 7.0
  • .NET Framework 3.5
  • Visual Studio 2008 (note that the SDK add-ins do not work with VS 2010).

Setting up the test service

In the real world you would be integrating your claims-aware application with an existing security token service that you will have no direct control over. In this example we will set up a test service that acts as a token service and uses SQL Server as the store for user and role information. Any user of your claims-aware web application will be sent here to enter their username and password before being passed back to the application.

This site can be created using one of the project templates installed by the WIF SDK in Visual Studio 2008:

  • Select File -> New Web Site…
  • Select “ASP.NET Security Token Service Web Site”
  • Select “File system” for the location as we will be using Visual Studio’s file system web server for these examples.
  • Select a directory to create the web site in.

This basic site will contain a login form and a default page. Although forms authentication will be enabled, it will not be not linked up to any data store. To create a more useful test service, we will link this site up to SQL Server membership and role providers to allow a range of roles and users to be created. It’s  not in the scope of this article to explain how to install SQL Server-based role and membership providers, but you’ll need to go through the following steps:

  • Remove all the controls and code from the Login.aspx file and add in an ASP.NET Login control.
  • Set up a new SQL Server database for membership and role data using the ASP.NET SQL Server registration tool.
  • Add a connection string to the web.config file called LocalSqlServer pointing to the SQL Server database.

You can use the ASP.NET Configuration tool to configure your providers and add a few test roles and users. This is available from the ASP.NET Configuration option in the Website menu in Visual Studio.

  • Select the Provider tab and click on “Select a different provider for each feature”.
  • Ensure that SqlMembershipProvider and SqlRoleManager are both selected
  • Click on the Security tab and start adding roles and users.

Fixing the threading issue

Before you use the site, there is a small “feature” that you’ll need to fix in the code of Default.aspx, as this throws a ThreadAbortException every time you log in. This is caused by the claims redirect and it can be safey caught by adding the code shown below to the large try block on the PreRender event of Default.Aspx:

catch (ThreadAbortException exception)
{
  //* You can safely ignore this exception which is being thrown by the redirect
}

You can test that the membership and role providers have been set up properly by running your test service. A login form will appear that will re-direct you to Default.Aspx if you have logged in successfully.

Note that when you login successfully when using the test token service directly, some code in the prerender event of Default.Aspx will throw an InvalidOperationException. Don’t worry about this, as the code is set up to re-direct authenticated users back to the website that they came from rather than deal with users who are logging in directly.

Adding role support to the test service

You can return pretty much any information you want from a token service – all the information about a user, including role memberships, are returned as different types of claim.

To return the correct roles for each user from our test service we will have to make a change to the code that creates the claims once a user has been authenticated. Have a look at the GetOutputClaimsIdentity method of the CustomSecurityTokenService class – this is where those claims are created in this test service.

By default, the method just adds in a single role claim for “Manager” using the code below:

outputIdentity.Claims.Add( new Claim( ClaimTypes.Role, "Manager" ) );

If you replace this with the code below that uses the role manager then the identity returned by the token service will include all the role memberships assigned to the user from the SQL Server database:

string[] roles = Roles.GetRolesForUser(principal.Identity.Name);
foreach (string role in roles)
{
  outputIdentity.Claims.Add(new Claim(ClaimTypes.Role, role));
}

Filed under ASP.NET, C#.