This article is the first in a series of three articles looking at using the Windows Azure Access Control Service to implement web site authentication using social identity providers. It will show how Microsoft, Yahoo and Google accounts can be used to authenticate users using their social identities and login credentials rather than requiring them to create credentials and an identity on the website itself.
Website Authentication using Social Identity Providers
In this scenario social identity providers will be used to authenticate users for an ASP.NET website. Microsoft, Google and Yahoo will be used as identity providers, and the Windows Azure Access Control Service (ACS) will be used to convert the security tokens and transform the claims to a common format for the website. A Google account with two-step authentication will then be used to provide administrative access to the site using rules in ACS.
Creating a Relying Party Application
The first step is to create a simple relying party application. This will be created as an ASP.NET application, which can be tested locally, and then deployed to Windows Azure Websites. To keep things as simple as possible, the application will consist of a default page, a page for site members and a page for site administrators.
The solution structure for the website is shown below.
Image may be NSFW.
Clik here to view.
The Default.aspx page can be viewed by anyone, but content in the Members folder requires that users are authenticated. This is configured in the Web.config file in the Members folder.
<?xmlversion="1.0"?> <configuration> <system.web> <authorization> <!-- Deny access to unauthorized users.--> <denyusers="?"/> </authorization> </system.web> </configuration>
|
The content in the admin folder required that the users are authenticated, and are members of the Admin role.
<?xmlversion="1.0"?> <configuration> <system.web> <authorization> <!-- Allow only users who are members of the Admin role. --> <allowroles="Admin"/> <denyusers="*"/> </authorization> </system.web> </configuration>
|
The Default.aspx contains links to the other two pages.
<%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="Default.aspx.cs"Inherits="RelyingPartyApp.Default"%> <!DOCTYPEhtml> <htmlxmlns="http://www.w3.org/1999/xhtml"> <headrunat="server"> <title>Relying Party Application</title> </head> <body> <formid="form1"runat="server"> <div>Welcome to the Relying Party Application!</div> <div><ahref="Members/Members.aspx">Members Page</a></div> <div><ahref="Admin/Admin.aspx">Admin Page</a></div> </form> </body> </html> |
The website is configured to be hosted in IIS at http://localhost/RelyingPartyApp. The homepage can be viewed in Internet Explorer.
Image may be NSFW.
Clik here to view.
Clicking on either the Members Page or Admin Page links will result in a 401.2 access denied message, as the user is not authenticated.
Image may be NSFW.
Clik here to view.
In the next section the website will be configured to use the Windows Azure Access Control Service (ACS) to provide website authentication using Microsoft Accounts.
Registering the Relying Party Application with ACS
In this stage the ASP.NET relying party application will be registered with the Windows Azure Access Control Service (ACS) and configured in ACS to use Microsoft Accounts as an identity provider. The web site will then be configured to use ACS to provide a security token to authenticate the users.
Creating a Namespace in ACS
At the time of writing the ACS functionality is being migrated to the new portal, the interface may well change going forward, but the principals will remain the same. Clicking on the Active Directory link in the portal will display the registered namespaces that can be sued for ACS. A new namespace will be added for this scenario.
Image may be NSFW.
Clik here to view.
The new namespace must be globally unique within ACS. Here the namespace acsscenario is created in the West Europe region.
Image may be NSFW.
Clik here to view.
After a couple of minutes the namespace will be activated and ready to use, the Manage button is used to open the namespace management portal.
Image may be NSFW.
Clik here to view.
Configuring a Relying Party Application
The next stage is to configure a relying party application in ACS. The Relm and Return URL will be set to the root URL for the application, which is http://localhost/RelyingPartyApp/ in my example. I also set this as the Name property, which is displayed in the portal, so that I know exactly which application it refers to. All other settings are left with the default values.
Image may be NSFW.
Clik here to view.
Not that SAML 2.0 is set for the security token format, and the lifetime of the tokens will be 600 seconds (10 minutes). Also note that “Windows Live ID” (Microsoft account) is selected as an identity provider, and that a new rule group will be created.
Configuring the Default Rule Group
A new default rule group was created for the relying party application. The rule group will not contain any rules, but these can be generated from the claims provided by ACS by clicking the Generate link.
Image may be NSFW.
Clik here to view.
When this is done a new rule will be added to pass-through the value of the nameidentifter claim from that “Windows Live ID” (Microsoft account) to the relying party application.
Image may be NSFW.
Clik here to view.
The rule group can now be saved to commit the changes.
Configuring the ASP.NET Relying Party Application to use ACS for Authentication
Now that the relying party application has been configured in ACS, it can be configured to request security tokens form ACS for authentication. In order to do this the Identity and Access Tool for Visual Studio will need to be installed, it is located here:
http://visualstudiogallery.msdn.microsoft.com/e21bf653-dfe1-4d81-b3d3-795cb104066e
Once this tool has been installed, a new Identity and Access option will appear on the web project context menu.
Image may be NSFW.
Clik here to view.
I find it easiest to use this wizard with the business identity provider option; to do this you will need the URI for the WS-Federation metadata for your ACS namespace. This is available on the Application Integration page of the ACS management portal.
Image may be NSFW.
Clik here to view.
This URI can be copy-pasted into the Identity and Access wizard. Note that the realm for the relying party application matches the realm that was specified in the ACS portal.
Image may be NSFW.
Clik here to view.
Clicking OK on the wizard will apply the configuration changes to the Web.config file that will configure the application to use ACS to retrieve security tokens.
The key change in the web site configuration is the replacing of the FormsAuthentication module with the WSFederationAuthenticationModule and SessionAuthenticationModule modules from the System.Identity model namespace.
<system.webServer> <modules> <removename="FormsAuthentication" /> <addname="WSFederationAuthenticationModule"type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"preCondition="managedHandler" /> <addname="SessionAuthenticationModule"type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"preCondition="managedHandler" /> </modules> </system.webServer> |
The authentication modules are configured to use the namespace in ACS as an issuer for security tokens using passive redirect.
<system.identityModel.services> <federationConfiguration> <cookieHandlerrequireSsl="false" /> <wsFederation passiveRedirectEnabled="true" issuer=https://acsscenario.accesscontrol.windows.net/v2/wsfederation realm=http://localhost/RelyingPartyApp/ requireHttps="false" /> </federationConfiguration> </system.identityModel.services> |
Testing Authentication with Windows Live ID
The application is almost ready to be tested, one small change that needs to be made first is the removal of the configuration that will deny anonymous users access to the home page of the website. This was added by the Identity and Access wizard, but since we have configured access restrictions to the members and admin pages, it is not required and can be commented out.
<system.web> <authorization> <!--<deny users="?" />--> </authorization> <authenticationmode="None" /> <compilationdebug="true"targetFramework="4.5" /> <httpRuntimetargetFramework="4.5"requestValidationMode="4.5" /> </system.web> |
The default page can be viewed as normal, but then the members page is accessed the browser is redirected through ACS to the Microsoft account login page.
Image may be NSFW.
Clik here to view.
When the user logs on with a valid Microsoft account, the following error page is displayed, stating that the certificate used by ACS is not trusted.
Image may be NSFW.
Clik here to view.
Adding a line to the identity model configuration can override the certificate check.
<system.identityModel> <identityConfiguration> <certificateValidationcertificateValidationMode="None" /> <audienceUris> <add value="http://localhost/RelyingPartyApp/" /> </audienceUris> <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <trustedIssuers> <add thumbprint="B52D78084A4DF22E0215FE82113370023F7FCAC4" name="https://acsscenario.accesscontrol.windows.net/" /> </trustedIssuers> </issuerNameRegistry> </identityConfiguration> </system.identityModel> |
Once this change has been made, the authenticated user will be able to view the members page.
Image may be NSFW.
Clik here to view.
The admin page will still be restricted as the user is not a member of the Admin role.
Authenticating with Google and Yahoo Accounts
Now that the website can use Microsoft Accounts for authentication it is sample to add other social identity providers, such as Yahoo and Google. No changes in the website will be required for this; the only changes that need to take place will be in the ACS portal.
In the portal we can see that “Windows Live ID” is the only configured identity provider.
Image may be NSFW.
Clik here to view.
Adding Additional Identity Providers
Clicking on the Add link will allow more to be added, in the first case, Google will be added.
Image may be NSFW.
Clik here to view.
Note that the ASP.NET relying party application is selected to use Google by default. Once the changes are saved, Yahoo can be added in the same way. The ACS namespace now has three configured identity providers.
Image may be NSFW.
Clik here to view.
Generating new Rules
As the new identity providers will all submit claims to ACS, the rule group needs to be configured to pass these claims to the relying party application. The new rules are shown below.
Image may be NSFW.
Clik here to view.
Note that as well as the nameidentifier claim, Google and Yahoo also include claims for name and emailaddress.
Testing the Application
When the user browses to the members page, they are redirected to ACS, which displays a list of the identity providers that can be used for the site.
Image may be NSFW.
Clik here to view.
Selecting Google will redirect the browser to the Google login page.
Image may be NSFW.
Clik here to view.
Once authenticated, Google asks the user if it is OK to send details of the account holders name and email address to ACS. (As I am writing this in Sweden, the text is appearing in Swedish.)
Image may be NSFW.
Clik here to view.
When this is accepted the members pave will be displayed. There will be a very similar procedure when using a Yahoo account.
Examining the Security Tokens and Claims
In this section the claims returned by the identity providers will be examined, along with the HTTP request sequence that is used to authenticate the user using ACS and the social identity providers.
Examining the Claims
In order to work effectively with the different social identity providers, it is important to understand the claims that are supplied by these providers. In order to do this, the members page can be modified to include a data grid control that can be data bound to the collection of claims.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Members.aspx.cs" Inherits="RelyingPartyApp.Members.Members" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Members Page</title> </head> <body> <form id="form1" runat="server"> <div>Welcome to the Members Page!</div> <div><a href="../Default.aspx">Home</a></div> <h1>Claims</h1> <asp:DataGridID="dgrClaims"runat="server"AutoGenerateColumns="false"> <Columns> <asp:BoundColumnHeaderText="Type"DataField="Type"/> <asp:BoundColumnHeaderText="Value"DataField="Value"/> </Columns> </asp:DataGrid> </form> </body> </html> |
The data grid can be data bound from the page load event.
using System; using System.Security.Claims; using System.Threading;
namespace RelyingPartyApp.Members { public partial class Members : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal asClaimsPrincipal;
if (claimsPrincipal != null) { dgrClaims.DataSource = claimsPrincipal.Claims; dgrClaims.DataBind(); } } } } |
The ClaimsPrincipal class is part of the System.Security.Claims, and allows claims to be viewed and manipulated by relying party applications.
Claims provided by Microsoft.
Image may be NSFW.
Clik here to view.
Claims provided by Google.
Image may be NSFW.
Clik here to view.
Claims provided by Yahoo.
Image may be NSFW.
Clik here to view.
The claims supplied by ACS and the different social identity providers are summarized in the table below.
Claim | Microsoft | Yahoo | |
Name Identifier | Yes | Yes | Yes |
Name | No | Yes | Yes |
No | Yes | Yes | |
Identity Provider | Yes | Yes | Yes |
From the tests It can be seen that Microsoft only provides the name identifier claim, whilst Google and Yahoo supply this as well as name and email claims. These claims will be used later on to integrate with the .NET Universal Profile Provider and create a profile on the website.
Examining the Security Token Exchange
In order to gain an understanding of how the authentication process takes place and the parties involved, the Fiddler2 web debugging tool will be used to intercept the web traffic.
The latest version of Fiddler2 can be downloaded here: http://www.fiddler2.com
In order to do this the configuration for the relying party in ACS and the Web.config file will need to be changed so that the host name of the computer, rather than localhost is used in the URLs. As the authentication exchange takes place over a secure channel, fiddler must be configured to intercept and decrypt HTTPS traffic. This is done in the Fiddler Options menu.
Image may be NSFW.
Clik here to view.
With those changes made, the authentication request sequence can be monitored. The monitoring trace for authentication with a Yahoo account is shown below.
Image may be NSFW.
Clik here to view.
The sequence is as follows, with the numbers representing the request sequence number.
· 1 – A request is made to the default page for the relying party application, resulting in a 200 response.
· 2 – A request is made to the members page, resulting in a 302 code, redirecting the browser to the acsscenario namespace in ACS.
· 4 – ACS processes the request and provides options for the user to select an identity provider.
· 11 – The request reaches login.live.com, and the Yahoo account authentication takes place.
· 32 – The browser is redirected to ACS again, with the transformed security token.
· 35 – The security token is sent to the application where it is intercepted by ACS and authentication takes place, a 302 code is used to redirect the browser to the members page.
· 36 – The authenticated user can now view the members page, and receive a 200 code.
In request 4, the request to ACS, the details regarding the WS-Federation authentication request can clearly be seen. These include the operation to be performed, the relying party application realm, the resource that was requested, and the current system time.
https://acsscenario.accesscontrol.windows.net/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2fwin7base%2fRelyingPartyApp%2f&wctx=rm%3d0%26id%3dpassive%26ru%3d%252fRelyingPartyApp%252fMembers%252fMembers.aspx&wct=2013-03-14T18%3a21%3a31Z HTTP/1.1 |
The security token sent in HTTP request 35 contains the SAML security token sent to the relying party by ACS. The information in the token is shown below, the certificate and signature values have been truncated.
It can be seen that the lifetime of the token is 10 minutes, the token applies to the application hosted at http://win7base/RelyingPartyApp/, and is issued from https://acsscenario.accesscontrol.windows.net/. The name identifier is specified as the subject name Id, and the email and name claims are specified as attributes.
<t:RequestSecurityTokenResponse Context="rm=0&id=passive&ru=%2fRelyingPartyApp%2fMembers%2fMembers.aspx" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"> <t:Lifetime> <wsu:Createdxmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-03-14T18:21:50.023Z</wsu:Created> <wsu:Expiresxmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-03-14T18:31:50.023Z</wsu:Expires> </t:Lifetime> <wsp:AppliesToxmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <EndpointReferencexmlns="http://www.w3.org/2005/08/addressing"> <Address>http://win7base/RelyingPartyApp/</Address> </EndpointReference> </wsp:AppliesTo> <t:RequestedSecurityToken> <Assertion ID="_b5e34903-dc8f-47f7-b369-488f0a19c3b4" IssueInstant="2013-03-14T18:21:50.023Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <Issuer>https://acsscenario.accesscontrol.windows.net/</Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /> <ds:Reference URI="#_b5e34903-dc8f-47f7-b369-488f0a19c3b4"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> <ds:DigestValue>6HWloBhG5oosH1Uc9B/noIiEp7E7DhL11/ANePeZWK4=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>Bq...TQ==</ds:SignatureValue> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <X509Data> <X509Certificate>MIID...==</X509Certificate> </X509Data> </KeyInfo> </ds:Signature> <Subject> <NameID>https://me.yahoo.com/a/r5swqoIjfda_5ZoxpdR95iX81df1uEGDfbCl#b6a9e</NameID> <SubjectConfirmationMethod="urn:oasis:names:tc:SAML:2.0:cm:bearer" /> </Subject> <ConditionsNotBefore="2013-03-14T18:21:50.023Z"NotOnOrAfter="2013-03-14T18:31:50.023Z"> <AudienceRestriction> <Audience>http://win7base/RelyingPartyApp/</Audience> </AudienceRestriction> </Conditions> <AttributeStatement> <AttributeName="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"> <AttributeValue>alanazuretest2@yahoo.com</AttributeValue> </Attribute> <AttributeName="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"> <AttributeValue>Alan Azure</AttributeValue> </Attribute> <AttributeName="http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider"> <AttributeValue>Yahoo!</AttributeValue> </Attribute> </AttributeStatement> </Assertion> </t:RequestedSecurityToken> <t:RequestedAttachedReference> <SecurityTokenReference d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_b5e34903-dc8f-47f7-b369-488f0a19c3b4</KeyIdentifier> </SecurityTokenReference> </t:RequestedAttachedReference> <t:RequestedUnattachedReference> <SecurityTokenReference d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_b5e34903-dc8f-47f7-b369-488f0a19c3b4</KeyIdentifier> </SecurityTokenReference> </t:RequestedUnattachedReference> <t:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</t:TokenType> <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType> <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType> </t:RequestSecurityTokenResponse> |
Windows Identity Foundation will validate this security token, and then use it to authenticate the user.
Adding a Site Administrator using a Google Account with Two-Phase Authentication
In this step the rules in ACS will be used to add a claim to a specific Google identity that will grant the user administrative privileges on the relying party application. The ASP.NET relying party application has an Admin folder which contains the Admin.aspx page.
Image may be NSFW.
Clik here to view.
The Web.config file specifies the authorization configuration that will only allow users who are a member of the admin role to access the folder content.
<?xmlversion="1.0"?> <configuration> <system.web> <authorization> <!-- Allow only users who are members of the Admin role. --> <allowroles="Admin"/> <denyusers="*"/> </authorization> </system.web> </configuration>
|
In order for a specific social identity to be able to access the Admin folder, a role claim with the value of Admin will need to be added to the security token that is sent from ACS to the relying party application.
Create a Rule in ACS to Assign the Admin Role Claim for a Specified Google Account
In order to create a rule to add a role claim to the security token we need to identify the identity uniquely. The claims that we have available are as follows:
Claim | Comments |
Name Identifier | Guaranteed to be unique and immutable for the identity. |
Name | No guarantee of uniqueness or immutability. |
Email Address | Guaranteed to be unique and immutable for the identity. |
Identity Provider | Supplied by ACS. |
The two claims that are contenders for identifying the identity are name identifier and email address. The value of the name identifier claim is typically not accessible, so the email address is the best candidate. Name is not suitable, as another user could create a Google account with the same name, and then gain administrative access to the website.
Not that if a Microsoft account was used the email claim would not be available, and the name identifier claim would have to be used. It may be challenging to obtain the value of the name identifier claim for a specific Microsoft account.
The pseudo code for the rule that will be created is as follows.
if (IdentityProvider == "Google"&& InputClaimType == "emailaddress" && InputClaimValue == " alanazuretest@gmail.com") { OutputClaimType = "role"; OutputClaimValue = "Admin"; } |
The rule can configuration in ACS is shown below.
Image may be NSFW.
Clik here to view.
Once this rule is saved in ACS the Google user with the email address alanazuretest@gmail.com will have administrative privileges on the site.
Configuring Two-Phase Authentication in Google
In order to increase security on the website, a two-step authentication scheme can be used. There are various ways to implement this, one of the most common options is to send a verification code to a mobile device. The alanazuretest@gmail.com Google account has been configured to send a verification code as an SMS message to my mobile phone when I login, the configuration for the account is shown below.
Image may be NSFW.
Clik here to view.
Test the Admin Authentication
The application can now be tested to verify that the user can access the administrative section of the site, and that the two-phase authentication functions correctly. When the user browses to the members page, the browser is redirected to the login page for Google, with a message stating that acscenario.accesscontrol.windows.net is requesting a security token.
Image may be NSFW.
Clik here to view.
When the user authenticates with the first stage of authentication, username and password, a SMS message containing an access code is sent to a mobile device.
Image may be NSFW.
Clik here to view.
The second stage of authentication prompts the user for this access code; a screenshot of this is shown below.
Image may be NSFW.
Clik here to view.
Once the user is authenticated, the browser is redirected back to the members page, where the supplies in the security token are displayed.
Image may be NSFW.
Clik here to view.
It can be seen that the rule claim has been supplied, with the value of Admin. This should now grant the user access to the admin page in the website.
Image may be NSFW.
Clik here to view.
Conclusions
In this scenario we have used ACS to add authentication by three of the largest social identity providers to a website. We have also configured a Google account to have administrative privileges on the website, and enabled a two-step authentication process on the account. We can see that the authentication model that is commonly used in Web.config files to grant access to specific users and groups integrates well with the claims-based model used by ACS.
We have also seen that different identity providers provide different claims, and that providing an application that can handle all types of identity providers may be challenging.