Over the past year, I've had several Windows Azure customers come to me asking for help with the same challenge. They already have a website secured using ASP.NET SQL Membership and roles but now want to add (not just replace) authentication with Windows Live ID, Google, Yahoo!, and Facebook accounts. For more information on Windows Azure, see "How to Build a Node.js REST API on Windows Azure Websites" and "Taking Windows Azure Virtual Machines for a Test Drive." What they want is something like what Figure 1 shows.

142581_fig1_website_authentication_options-sm
Figure 1: Desired ASP.NET website authentication options

Sound familiar to you? If so, read on as we explore how you can use the Access Control Service (ACS) in combination with some open-source software to let you have your cake and eat it, too -- that is, to allow your website to support a variety of authentication providers.

The Missing Piece

For those familiar with federated security architectures, the missing piece is a Security Token Service (STS) that knows how to read logins from SQL Membership and issue tokens that ACS will recognize. In the end, your website need only trust tokens from ACS, but it will still allow users to log in with their accounts stored in SQL Membership. You could certainly write your own custom STS to handle this task; however, the open-source community already provides a fantastic, Azure-friendly solution in the form of thinktecture IdentityServer. Figure 2 shows how IdentityServer fits into the authentication architecture shown in Figure 1.

142581_fig2_authentication_architecture-sm
Figure 2: Authentication architecture incorporating IdentityServer

 

What Is IdentityServer?

IdentityServer is an open-source STS that was created, developed, and tested exclusively by security guru Dominick Baier of Thinktecture. The fact that IdentityServer is open-source means you can both customize it to suit your needs and use it as a reference to learn from. The fact that IdentityServer is free means you're running out of reasons to not try it out!

IdentityServer ships as a Visual Studio 2010 solution that can be packaged in one of two ways: to run on-premises (within Microsoft IIS) or within a hosted service on Windows Azure. For this article, we'll publish IdentityServer to its own hosted service on Azure. You can even take this approach a step further and integrate it with your existing Web role to save on compute costs. Although I won't show the steps to accomplish this, doing so is quite possible and works well.

IdentityServer's major features are as follows:

  • support for multiple protocols (WS-Trust, WS-Federation, OAuth2, Web Resource Authorization Protocol -- WRAP, JSnotify, HTTP GET)
  • multiple-token format support (SAML 1.1/2.0, SWT)
  • out-of-the-box integration with ASP.NET membership, roles, and profiles
  • support for username/password and client certificate authentication
  • support for WS-Federation metadata
  • support for WS-Trust identity delegation
  • extensibility points to customize configuration and user management handling

Naturally, what we're most interested in within the context of this article is IdentityServer's out-of-the-box integration with ASP.NET membership, roles, and profiles and its support for WS-Federation (which is what we need in the website scenario).

Before You Begin

To get started with IdentityServer, you'll need these items:

  • an Azure storage account, as well as the account name and key to access it
  • the connection string to your SQL Membership database running in SQL Azure
  • an ACS namespace
  • an Azure subscription in which you can create a hosted service
  • the download of IdentityServer v.1.0.1 On-Premise+Azure (source)

With these items in hand, you're ready to begin configuration and deployment.

Create Your ACS Namespace

IdentityServer requires an ACS namespace. You can create a namespace by following these steps:

  1. Within the Windows Azure Portal, click the Service Bus, Access Control & Caching tab, then click Access Control in the tree view.
  2. Click the New {} button. Enter a name for your new namespace, select a Country/Region and Subscription, and click Create Namespace.

This process might take 5 to 10 minutes or so to provision the namespace.

Configuring IdentityServer Pre-deployment

The next step is to update several settings prior to IdentityServer deployment. To do so, within the IdentityServer download opened in Visual Studio, open the ServiceConfiguration.cloud.cscfg file. Update the Azure Storage connection string values for the settings with the names Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString and StorageConnectionString, respectively, so that they point to your Azure Storage account.

Next, update IdentityServer to use your SQL Azure database for membership. Open repositories.config (under the \Website\Configuration folder) and ensure that the userManagement attribute is set to use the ProviderUserRepository as shown in Figure 3.

<thinktecture.identityServer.repositories tokenServiceConfiguration="..." userManagement="Thinktecture.IdentityServer.Repositories.ProviderUserRepository, Thinktecture.IdentityServer.Core.Repositories"
relyingParties="..." .../>

Finally, from the \Website\Configuration folder, open connectionStrings.config and change the value of the single connection string (ProviderDB) there so that it points to your SQL Azure database.

Add IdentityServer Users

Your final configuration step is to create the two SQL Membership roles and two users required by IdentityServer in your membership database. You can create these using your website's existing user interface or by using the ASP.NET configuration website that's available when you have the Website project selected (from the Project menu, select ASP.NET configuration). Figure 4 shows the roles and users you need to create. You can provide any usernames you like in place of the ones shown, but the role names must be entered exactly as listed.

142581_fig4_IdentityServer_users_and_roles

Create Your Hosted Service and SSL Certificate

From the Windows Azure Portal, create a new hosted service. Next, acquire an SSL certificate or create a self-signed certificate to use during development. You'll want to use SSL for authentication, and you can use the same certificate that's used for authentication to sign encrypted data with. Click the Certificates folder, which is under the hosted service you just created, and click the Add Certificate button at the top to select your certificate.

Next, in Visual Studio open ServiceConfiguration.Cloud.cscfg. Ensure that the value attributes for the SslCertificateDistinguishedName and SigningCertificateDistinguishedName are both set to the distinguished name (DN) of the certificate you previously uploaded, as shown in Figure 5.

<Setting name="SslCertificateDistinguishedName" value="CN=<service>.cloudapp.net" />
<Setting name="SigningCertificateDistinguishedName" value="CN=<service>.cloudapp.net" />

Then, under those settings, set the thumbprint attribute for the Certificate entry with the name SSL to the thumbprint of the certificate you uploaded, as shown in Figure 6.

<Certificate name="SSL" thumbprint="2E4FABB5..." thumbprintAlgorithm="sha1" />

Configure Your Website as an ACS Relying Party

Your website must trust ACS to perform the authentication function for the website. To set up this trust arrangement, you must configure your existing website as a relying party of ACS. To do so, follow these steps:

  1. Open your website in Visual Studio; in your project folder, right-click the website project and select Add STS Reference.
  2. Enter the path to web.config (of your website) in the Application configuration location text box in the Federation Utility wizard. Then in the Application URI text box, enter the URI from which the application will be accessed (usually this URI is the full DNS name used for your website). Be sure the URI specifies HTTPS as the protocol.
  3. On the Security Token Service screen, select Use an existing STS and in the STS WS-Federation metadata document location text box, paste the URI of the federation metadata document for your namespace in ACS. You can get this URI by visiting the ACS Portal in the browser for your service namespace, then clicking the Application integration link and copying the URI for WS-Federation Metadata from the Endpoint Reference table. Paste that value into the text box and click Next.
  4. On the STS signing certificate chain-validation error screen, select Disable certificate chain validation. This setting is required when you're using a self-signed certificate. For production, you'd want to use a certificate issued by Certificate Authority (CA) and opt to select Enable certificate chain validation. Click Next.
  5. On the Security token encryption dialog box, select No encryption and click Next.
  6. On the Offered claims screen, click Next.
  7. On the Summary screen, click Finish.

To authorize your website to be a relying party of ACS within your service namespace, you need to create the relying party in ACS and edit a few values in your website's web.config file. Here are the steps to do so:

1. Go to the ACS portal for your service namespace and click Relying party applications.

2. Click Add.

3. Fill in the following settings:

    a. For the name, enter a name.

    b. For the mode, select Enter settings manually.

    c. For the Realm, enter the URI used to access your website.

    d. For the Return URL, enter the same URL (the one used to access your website).

    e. You can leave the rest of the settings at their default values.

Deploy to Azure

Before you can complete the configuration, you must be able to access a running instance of IdentityServer. Thus, you need to deploy IdentityServer to Azure.

To do this, within the IdentityServer solution that's open in Visual Studio, right-click WebSite (WindowsAzure).Azure cloud project and select Package. In the dialog box that appears, shown in Figure 7, ensure that Cloud and Release are the options chosen for Service configuration and Build configuration, respectively, and click Package.

142581_fig7_Visual_Studio_Package_dialog
Figure 7: The Visual Studio Package dialog box

When the package is ready, deploy it to the production slot in the hosted service you created previously, using the Windows Azure Portal. You'll also need to deploy the updated version of your website.

Configure IdentityServer as an Identity Provider in ACS

After the package is deployed and running, navigate to the address for IdentityServer (e.g., "https://sts.tejadanet.com") in a browser. You'll be prompted by the browser with a security warning about the certificate, if you used a self-signed certificate. Choose the option to continue, or add an exception and continue as appropriate in your browser. You'll then see the IdentityServer home page, which Figure 8 shows.

142581_fig8_IdentityServer_home_page-sm
Figure 8: IdentityServer home page

Right-click the View WS-Federation Metadata link, and save the file (FederationMetadata.xml) to your desktop. Next, return to the ACS Portal for your service namespace. Click the Identity providers link at the left. In the screen that appears, click Add. On the Add Identity Provider screen, select WS-Federation identity provider and click Next.

On the Add WS-Federation Identity Provider screen, enter IdentityServer in the Display name text box, as shown in Figure 9.

142581_fig9_finishing_Identity_Provider_config-sm
Figure 9: Finishing the Identity Provider configuration

Under the WS-Federation metadata section, select the File option and click the Browse button to select the FederationMetadata.xml document you downloaded previously from IdentityServer. In the Login link text box, enter the text you want to appear to users in their home-realm login page. Finally, ensure that Sample Website is selected under Relying party applications.

Click Save, then click the Rule groups link. On the screen that appears, click the Default Rule Group for <your Website>. Next, on the Edit Rule Group screen, click the Generate link above the Rules table. On the Generate Rules screen that follows, check the boxes for IdentityServer and Windows Live ID and click Generate. The Rule Group should now be configured for both Windows Live ID and IdentityServer providers, as shown in Figure 10.

142581_fig10_viewing_generated_rules-sm
Figure 10: Viewing the generated rules

Configure ACS as a Relying Party of IdentityServer

Return to the IdentityServer home page. Click the sign in link at the top, enter your Administrator username and password that you created previously, and click the administration link, also in the top menu. Click the Relying Parties link, then click the Add New link.

In the Relying Party dialog box that's displayed next, for Relying Party Name, enter ACS (or whatever value you prefer). For the Realm URI, enter the URI using the form "http://<namespace>.accesscontrol.windows.net/", substituting your ACS service namespace. For ReplyTo URL, enter the WS-Federation endpoint in ACS for your service namespace, using the form "https://<namespace>.accesscontrol.windows.net/v2/wsfederation" (note the use of https).

Click Create. You should now see ACS in the list of Relying Parties for IdentityServer. With this, you've completed the necessary configuration. Now it's time to try out IdentityServer!

Trying It Out

Open a browser, and navigate to the address of your website via HTTPS (e.g., "https://www.tejadanet.net/"). Again, accept any warnings about the SSL certificate. You'll be redirected to the home-realm discovery login page, as shown in Figure 11.

142581_fig11_home-realm_discovery_login-sm
Figure 11: The home-realm discovery login page

Notice that you can log in with either a Windows Live ID or SQL Membership (or whatever you named the link in your identity provider configuration). Choose SQL Membership. You'll be redirected to IdentityServer, as shown in Figure 12.

142581_fig12_login_screen_SQL_Membership_users-sm
Figure 12: The login screen seen by SQL Membership users

Log in with the user account you created earlier. You should be redirected to your website and are now logged in.

The Best of Both Worlds

You can see how ACS in combination with IdentityServer lets you have the best of both worlds. You can log in with the SQL Membership users you already have, as well as add other providers such as Windows Live ID, Google, Yahoo!, and Facebook. The addition of these providers gives users of your website more authentication options, making it easier for users to access your site by using the authentication that's most convenient for them.