Enhancing an ASP.NET Membership Provider Website with by uqg17706

VIEWS: 0 PAGES: 33

									Hands-On Lab
Enhancing an ASP.NET Membership
Provider Website with Identity Provider
Capabilities
Lab version: 1.0.0

Last updated: 3/25/2010
Contents

OVERVIEW ................................................................................................................................................... 3

EXERCISE 1: ENHANCE AN ASP.NET MEMBERSHIP WEBSITE WITH IDENTITY PROVIDER
CAPABILITIES AND USE IT FROM A THIRD PARTY WEBSITE............................................................ 12
       Task 1 - Preparing the Solutions ......................................................................................................... 12
       Task 2 - Inspecting the Initial Solution ................................................................................................ 14
       Task 3 - Creating the Passive STS Page ............................................................................................... 15
       Task 4 - Creating the Partner Web Site ............................................................................................... 18
       Task 5 - Validating the STS Issues Tokens to a Specific Relying Party ................................................. 25
       Task 6 - Customizing Authorization with Different Roles ................................................................... 26
   Exercise 1: Verification ............................................................................................................................ 27

SUMMARY .................................................................................................................................................. 33
Overview
Contrary to what you may have heard, reaping the benefits of claims-based identity & access
management does not necessarily require any rip & replace intervention on your existing asset. In this
short hands-on lab we will demonstrate how you can easily enhance a common ASP.NET membership
provider website with identity provider capabilities, enabling new scenarios without disrupting the
existing functionalities or your user’s experience. Furthermore, we will do all this without requiring any
special security knowledge. The code we will demonstrate is not production ready, of course; however it
should be enough for giving you idea of the general application’s structure.
 Let’s assume that you are running a website which manages authentication via the mechanisms offered
by ASP.NET Membership: the user store is based on SqlMembershipProvider, the credential gathering is
implemented via forms authentication plus Login web control, roles and profile information are
managed via the usual ASP.NET classes.
Let’s also assume that you have a business partner, running a website as well, which would like to be
able to offer special conditions to your users: recognize them as your users, personalize the experience
or handle authorization according to user information you keep in your profiles or roles, perhaps even
achieve single sign on between your site and theirs. In other words, your business partner would like to
use your website as an Identity Provider (IP). Traditionally, the trivial solutions to the problem (like
duplicating credentials stores and keeping them synchronized) would require so much work that it
would seldom make business sense: however claims based identity and the Windows Identity
Foundation Framework lower the bar, making the above significantly easier to implement and maintain.
The Windows Identity Foundation Framework solution can be extremely simple: we just publish an extra
page in our website, whose sole purpose is offering an entry point to our application when a user of ours
wants to sign in a third party partner website. Such a page, which in the identity jargon takes the name
of passive Security Token Service (or passive STS), will understand requests presented via standard
protocol (in our exercise it will be WS-Federation, but the principle holds for other protocols as well) and
will return the requested values using the same conventions. The use of standards not only guarantees
that the third party website will be free to leverage whatever technology or platform uses the same
standard, but also makes possible the use of specific tooling for automating many of those processes
and hiding away the details of the specific implementation.
This hands-on lab will help you to apply the solution described above, by enhancing an existing APS.NET
website with a simple STS and by configuring another website to take advantage of that STS.


Objectives
In this Hands-On Lab, you will learn how to:
       Enhance an ASP.NET website with membership provider with identity provider capabilities
       Configure an ASP.NET website to accept and authorize users from an external identity provider


System Requirements
You must have the following items to complete this lab:

       Microsoft® Windows® Vista SP2 (32-bits or 64-bits) , Microsoft® Windows Server 2008 R2|SP2
        (32-bit or 64-bit), Microsoft® Windows® 7 RTM (32-bits or 64-bits)
       Microsoft® Internet Information Services (IIS) 7.0
       Microsoft® .NET Framework 3.5
       Microsoft® Visual Studio 2008
       Microsoft® SQL Express 2008

       Microsoft® Windows Identity Foundation Runtime

       Microsoft® Windows Identity Foundation SDK


Setup
You must perform the following steps to prepare your computer for this lab.
    1. Run the command file SetupLab.cmd located at
       %YourInstallationtFolder%\Labs\MembershipAndFederation\Source\Setup as administrator
       (right-click the SetupLab.cmd file and select Run as administrator).

         Note: For convenience, much of the code is available as Visual Studio code snippets. This
         command file checks the lab dependencies and launches the Visual Studio installer file that
         installs the code snippets and then it installs the required certificates.



    2. When the Visual Studio Content Installer is shown, choose all items from the list and click Next.
   Figure 1
   Code snippets for exercise


3. A dialog window appears warning that the file is not signed; choose Yes to proceed anyway.




   Figure 2
   Warning dialog window


4. When prompted for the location of the C# snippets, highlight all snippets, click the check box
   next to My Code Snippets under the Visual Studio 2008 node, and click Next.




   Figure 3
   Installation location for C# code snippets


5. When prompted for the location of the XML snippets, highlight all snippets, click the check box
   next to My Xml Snippets under the Visual Studio 2008 node, and click Next.
   Figure 4
   Installation location for XML code snippets


6. Click Finish to install the code snippets.
   Figure 5
   Installation confirmation for lab snippets


7. The installation should proceed and install all snippets.
   Figure 6
   Installation finished


8. Click Close to dismiss the confirmation dialog.

     Note: Next, the setup script will proceed by replacing any existing localhost certificate with a
     new one. If you already have a "localhost" certificate needed by another application, ensure to
     make a back up copy of it before continue with the lab's certificates installation.



9. Once closed the code snippets installer, the setup script will proceed with the certificates
   installation. Press Y if you want to continue with the required certificates installation.
       Figure 7
       Installing the localhost certificate

         Note: If you are running Windows 7 or Windows 2008 R2 you might not see this window.



    10. When finished press any key to close the setup console.


 Note: In addition to the setup script inside the
 %YourInstallationFolder%\Labs\MembershipAndFederation\Source\Setup folder, there is a
 Cleanup.cmd file you can use to uninstall all the code snippets installed by the SetupLab.cmd script.




Exercises
The following exercise makes up this Hands-On Lab:
    1. Enhance an ASP.NET Membership Website with Identity Provider Capabilities and Use it from a
       Third Party Website
 Note: Each exercise is accompanied by a starting solution. These solutions are missing some code
 sections that are completed through each exercise and therefore will not work if running them
 directly.
 Inside each exercise you will also find an end folder where you find the resulting solution you should
 obtain after completing the exercises. You can use this solution as a guide if you need additional help
 working through the exercises.



Estimated time to complete this lab: 25 minutes.
Exercise 1: Enhance an ASP.NET
Membership Website with Identity
Provider Capabilities and Use it from a
Third Party Website
In this exercise you will enhance an existing ASP.NET website which uses the membership provider with
a passive STS page so it can work as an identity provider for other websites. Then, you will configure a
second website to take advantage of it (or, using the common security terminology, federate with it).




Figure 8
The general flow of the exercise’s solution


Task 1 - Preparing the Solutions
In this task you will take an existing website and configure it for using a pre-populated membership
store file (ASPNETDB.mdf). In practical terms, this means giving write permissions to NETWORK SERVICE
(or IIS_IUSRS for Windows 7 and Windows Server 2008 R2) for the App_Data folder in order to allow IIS
to read and write the ASPNETDB.mdf database.
    1. Open Microsoft Visual Studio 2008 with administrator privileges. From Start | All Programs |
       Microsoft Visual Studio 2008, right click on Microsoft Visual Studio 2008 and choose Run as
       administrator.
    2. Open the MembershipSite.sln solution file located in the
       %YourInstallationFolder%\Labs\MembershipAndFederation\Source\Ex1-
       EnhancingWithFederation\Begin folder.
    3. Open a Windows Explorer instance and browse to the folder
       %YourInstallationFolder%\Labs\MembershipAndFederation\Source\Ex1-
       EnhancingWithFederation\Begin\MembershipSite.
    4. Assign Write permission to NETWORK SERVICE (or IIS_IUSRS for Windows 7 and Windows
       Server 2008 R2) user for the App_Data folder of the Begin solution. To do this, right-click the
       App_Data folder, select Properties, go to the Security tab and click Edit. On the Permissions for
       App_Data select the "NETWORK SERVICE" user and check the Write permission. Click OK on
       each dialog.




       Figure 9
        Assigning NETWORK SERVICE write permissions for App_Data



          Note: If you want to run the End solution, follow the same steps in the
          %YourInstallationFolder%\Labs\MembershipAndFederation\Source\Ex1-
          EnhancingWithFederation\End\MembershipSite folder.




Task 2 - Inspecting the Initial Solution
    1. Go back to the solution in Visual Studio.
    2. Press F5 to run the Web site and accept to enable debugging in the Web site.
    3. When redirected to the login page enter the username John and the password p@ssw0rd




        Figure 10
        Log in page


    4. Click Log In button.
       Figure 11
       Default page showing a welcome message for the authenticated user


    5. Close the browser.

         Note: You can continue inspecting Web.config file. The web site is configured as any usual
         ASP.NET Web site to use Forms authentication method with the SQL membership provider. In
         the following task you will modify this website adding a passive STS page which will reuse the
         same membership mechanism.




Task 3 - Creating the Passive STS Page
    1. On the Solution Explorer, right-click the project (https://localhost/MembershipSiteEx01) and
       select Add New Item.
    2. Add a new Web Form and use the name PassiveSTS.aspx.
    3. Add a reference to the Microsoft.IdentityModel.dll assembly to the partner Web site. To do
       this, right-click on the https://localhost/MembershipSiteEx01 project, select Add Reference
       and add the Microsoft.IdentityModel component in the .NET tab.

         Note: If you did not find the Microsoft.IdentityModel.dll assembly on the Add Reference
         dialog, you can add the reference including the following line in the
         configuration/system.web/compilation/assemblies section of the Web.config file:
         <add assembly="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
         PublicKeyToken=31BF3856AD364E35" />
4. Open the PassiveSTS.aspx.cs page.
5. Add the following code to the PassiveSTS class


   C#
   using    System;
   using    System.Collections.Generic;
   using    System.Linq;
   using    System.Web;
   using    System.Web.UI;
   using    System.Web.UI.WebControls;
   using    Microsoft.IdentityModel.Protocols.WSFederation;
   using    Microsoft.IdentityModel.Web;
   using    Microsoft.IdentityModel.SecurityTokenService;
   using    System.Globalization;

   public partial class PassiveSTS : System.Web.UI.Page
   {
       protected void Page_Load(object sender, EventArgs e)
       {

        }

       protected void Page_PreRender(object sender, EventArgs e)
       {
           string action =
   Request.QueryString[WSFederationConstants.Parameters.Action];

             try
             {
               if (action == WSFederationConstants.Actions.SignIn)
               {
                   // Process signin request.
                   SignInRequestMessage requestMessage =
   (SignInRequestMessage)WSFederationMessage.CreateFromUri(Request.Url);
                   if (User != null && User.Identity != null &&
   User.Identity.IsAuthenticated)
                   {
                       SecurityTokenService sts = new
   MembershipSTS(MembershipSTSConfiguration.Current);
                       SignInResponseMessage responseMessage =
   FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(requestMes
   sage, User, sts);

   FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(responseM
   essage, Response);
                   }
                   else
                       {
                            throw new UnauthorizedAccessException();
                       }
               }
               else if (action == WSFederationConstants.Actions.SignOut)
               {
                   // Process signout request.
                   SignOutRequestMessage requestMessage =
   (SignOutRequestMessage)WSFederationMessage.CreateFromUri(Request.Url);

   FederatedPassiveSecurityTokenServiceOperations.ProcessSignOutRequest(requestMe
   ssage, User, requestMessage.Reply, Response);
               }
               else
               {
                    throw new InvalidOperationException(
                        String.Format(CultureInfo.InvariantCulture,
                                       "The action '{0}'
   (Request.QueryString['{1}']) is unexpected. Expected actions are: '{2}' or
   '{3}'.",
                                       String.IsNullOrEmpty(action) ? "<EMPTY>" :
   action,
                                       WSFederationConstants.Parameters.Action,
                                       WSFederationConstants.Actions.SignIn,
                                       WSFederationConstants.Actions.SignOut));
               }
           }
           catch (Exception exception)
           {
               throw new Exception("An unexpected error occurred when processing
   the request. See inner exception for details.", exception);
           }
       }
   }


     Note: This code is the same code created by the ASP.NET Security Token Service Web Site
     Visual Studio template. It provides the basic functionality of a passive token issuer that
     supports sign-in and sign-out. The solution will not compile right now, but in the following
     steps you will add a couple of assets that will make it work.

6. Open a windows explorer window and browse to
   %YourInstallationFolder%\Labs\MembershipAndFederation\Source\Assets.
7. Copy the App_Code and FederationMetadata folders and its content to the Web site folder
   (right-click the project https://localhost/MembershipSiteEx01/ and select Open Folder in
   Windows Explorer, then paste the files in the project folder).
8. Switch back to Visual Studio and click Refresh button on the Solution Explorer window.
       Figure 12
       App_Code and FederationMetadata folders added



         Note: The code you just added is a simplified version of the code generated by the Windows
         Identity Foundation Visual Studio templates. The STS will issue claims with the user name and
         the roles he has. For further understanding you can inspect the files just added and take a look
         at the GetOutputClaimsIdentity method in the MembershipSTS class. This is the method that
         we can use for customizing the identity information in the token that we will send to the third
         party website.




Task 4 - Creating the Partner Web Site
    1. On Visual Studio go to File | Add | New Web Site.
    2. On the New Web Site dialog select ASP.Net Web Site project type, choose HTTP for the
       location and make sure language is set to Visual C#, and then provide the following name for
       the web site: https://localhost/MembershipSitePartnerEx01/ and click OK.
    3. Add a reference to the Microsoft.IdentityModel.dll assembly to the partner Web site. To do
       this, right-click on the https://localhost/MembershipSitePartnerEx01/ project, select Add
       Reference and add the Microsoft.IdentityModel component in the .NET tab.

         Note: If you did not find the Microsoft.IdentityModel.dll assembly on the Add Reference
         dialog, you can add the reference including the following line in the
         configuration/system.web/compilation/assemblies section of the Web.config file:
     <add assembly="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
     PublicKeyToken=31BF3856AD364E35" />

4. Update the Default.aspx page to add a FederatedPassiveSignInStatus control and a welcome
   message and set the body background color to #AFC1CE to differentiate the partner site from
   the membership site.
   ASPX
   <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
   Inherits="_Default" %>
   <%@ Register assembly="Microsoft.IdentityModel, Version=3.5.0.0,
   Culture=neutral, PublicKeyToken=31bf3856ad364e35"
   namespace="Microsoft.IdentityModel.Web.Controls" tagprefix="idfx" %>

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml">
   <head runat="server">
       <title>Membership and Federation - Exercise 1</title>
   </head>
   <body style="background:#AFC1CE">
       <form id="form1" runat="server">
       <div>
           <h1>Welcome to your partner site</h1>
         <idfx:FederatedPassiveSignInStatus ID="SignInStatus1" runat="server" />
       </div>
       </form>
   </body>
   </html>



5. On the Solution Explorer, right-click the https://localhost/MembershipSitePartnerEx01/
   project and select Add STS reference.
   Figure 13
   Add STS reference option


6. When the Federation Utility window shows up perform the following tasks for each step in the
   wizard.
       a. On the Welcome page click Next to continue using the pre-populated fields.
    Figure 14
    Welcome page


b. On the STS options page, select the third option button ("Use an existing STS"), set the
   STS metadata location to
   https://localhost/MembershipSiteEx01/FederationMetadata/2007-
   06/FederationMetadata.xml and click Next.
   Figure 15
   Selecting a STS option


c. Click Next. The following warning message will popup saying that there is a mismatch
   between the DNS name of the machine and the certificate subject name in the
   federation metadata. If the existing STS would have been a production deployed STS,
   then this could be a hint that you shouldn’t trust on it, but in a development
   environment it’s ok to continue.




   Figure 16
     Warning message because of certificate and DNS name mismatch on the development
     environment


d. Click Yes
e. Select the Enable encryption option and then select the Select an existing certificate
   from store option.




     Figure 17
     Using encryption with localhost certificate


f.   Click Select Certificate and select the certificate for localhost.
    Figure 18
    Selecting the certificate


g. Click Next.
h. In the Offered Claims page, click Next.
                  Figure 19
                  Offered claims window


             i.   On the Summary page, review the changes and click Finish.




                  Figure 20
                  Summary



Task 5 - Validating the STS Issues Tokens to a Specific Relying Party
To add additional security to the STS, you can limit the issuance of tokens to specific relaying parties
only. In this task, you will configure the STS to issue tokens for the partner site only.
    1. Open the MembershipSTS.cs file from the https://localhost/MembershipSiteEx01/ project
       inside the App_Code folder.
    2. Update the GetScope method to validate the AppliesTo property and throw an exception is the
       URI is not from the partner site. To do this, update the GetScope method as follows.
        (Code Snippet - Membership And Federation Lab - Ex 1 AppliesTo Validation)
        C#
       protected override Scope GetScope(IClaimsPrincipal principal,
       RequestSecurityToken request)
       {
           Uri rpUri = new Uri("https://localhost/MembershipSitePartnerEx01/");

           if (!request.AppliesTo.Uri.Equals(rpUri))
           {
               throw new InvalidRequestException(String.Format("The AppliesTo address
       {0} is not valid.", request.AppliesTo.Uri.AbsoluteUri));
           }

           Scope scope = new Scope(request,
       SecurityTokenServiceConfiguration.SigningCredentials);
           scope.EncryptingCredentials = new
       X509EncryptingCredentials(CertificateUtil.GetCertificate(StoreName.My,
       StoreLocation.LocalMachine, "CN=localhost"));
           scope.ReplyToAddress = scope.AppliesToAddress + "/Default.aspx";
           return scope;
       }



         Note: The AppliesTo will return the URL for the Relying Party that is requesting for tokens to
         the STS. In the previous code you are checking that the Relying Party that is requesting the
         token is a valid one.




Task 6 - Customizing Authorization with Different Roles
    1. Add a new Web Forms to the https://localhost/MembershipSitePartnerEx01 project and name
       it SecretPage.aspx.
    2. Add the following message to the SecretPage.aspx.
       ASPX
       <%@ Page Language="C#" %>

       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

       <html xmlns="http://www.w3.org/1999/xhtml">
       <head runat="server">
           <title></title>
       </head>
       <body style="background:#AFC1CE">
           <form id="form1" runat="server">
           <div>
           <p>This is a secret page; you can get here only if you are a manager.</p>
           </div>
           </form>
       </body>
       </html>



    3. Open the Web.config file from the https://localhost/MembershipSitePartnerEx01 project.
    4. Add the following settings under the configuration element to enable access to
       SecretPage.aspx only for users in Manager role.
       (Code Snippet - Membership And Federation Lab - Ex 1 SecretPage.aspx Authorization Settings)
       XML
       <configuration>
         ...
         <connectionStrings/>
         <location path="SecretPage.aspx">
           <system.web>
             <authorization>
               <allow roles="Manager"/>
               <deny users="*"/>
             </authorization>
           </system.web>
         </location>
         <location path="FederationMetadata">
         ...
       </configuration>



         Note: this is plain old ASP.NET configuration. It will work because the token contains role
         claims (http://schemas.microsoft.com/ws/2008/06/identity/claims/role) and the
         ClaimsPrincipal implements IsInRole by checking the list of claims where claim type is the one
         defined above.



    5. Build the solution, to do this press CTRL+SHIFT+B




Exercise 1: Verification


    1. Open a browser and navigate to https://localhost/MembershipSitePartnerEx01/.
Figure 21
Log in page from MembershipSiteEx01



 Note: You were redirected to the Log in page from MembershipSiteEx01 since
 MembershipSitePartnerEx01 is federating the authentication to MembershipSiteEx01. Once
 you get logged in you will be redirected back to the MembershipSitePartnerEx01.



 Note: If you want to run the End solution, assign Write permission to NETWORK SERVICE user
 (or IIS_IUSRS for Windows 7 and Windows Server 2008 R2) in the App_Data folder of the End
 solution.



 Note: if your SQL Express instance name is other than SQLEXPRESS, add the following
 configuration to the web.config under the Web Site https://localhost/MembershipSiteEx01
 (show in bold):
 <connectionStrings>
       <remove name="LocalSqlServer"/>
       <add name="LocalSqlServer" connectionString="data
 source=.\<YOURINSTANCESQLEXPRESSNAME>;Integrated
 Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
 providerName="System.Data.SqlClient"/>
 </connectionStrings>
2. Enter valid credentials (john/p@ssw0rd) and click Log In.




   Figure 22
   Logged in MembershipSitePartnerEx01



     Note: Notice that you logged in MembershipSiteEx01 and now you are authenticated in the
     MembershipSitePartnerEx01 also.



3. Browse to https://localhost/MembershipSitePartnerEx01/SecretPage.aspx
   Figure 23
   Access Denied for user John



     Note: The current user John does not have the required role for accessing the SecretPage.aspx



4. Go back (press backspace key).
5. Click on Sign out.
6. Log in using the Paul's credentials. Enter the username paul and the password p@ssw0rd
7. Now browse to https://localhost/MembershipSitePartnerEx01/SecretPage.aspx




   Figure 24
   Access granted for user Paul


8. Go back (press backspace key).
9. Click Sign out.
10. Navigate to https://localhost/MembershipSiteEx01/, enter valid credentials (john/p@ssw0rd)
    and click Log In.
   Figure 25
   Logged in MembershipSiteEx01


11. Now browse to https://localhost/MembershipSitePartnerEx01/




   Figure 26
   Logged in MembershipSitePartnerEx01 without Authenticating Again (Single Sign On)



    Note: You did not have to enter your credentials again since the web site is federating against
    the same STS which you already have a cookie for.
    The STS will issue tokens only when the AppliesTo element of the RequestSecurityToken is
    equal to https://localhost/MembershipSitePartnerEx01. As an extra exercise you can try
    creating another relying party website and configure it to federate against this STS. It will
    throw an exception.



12. Close the Web browser.
Summary
In this hands-on lab we explored one way of taking advantage of the advanced capabilities of Windows
Identity Foundation Framework in a very common scenario, collaboration between partner websites,
without having to become security experts. There are many other ways in which claims-based identity
and Windows Identity Foundation Framework could be used for enhancing websites: if you want to
know more, you can go though the other hands-on labs in the Identity Developer Training Kit, or refer to
the Windows Identity Foundation Framework SDK samples.

								
To top