Exercise 1: Enabling Federated Authentication for ASP.NET applications in Windows Azure

Securing an ASP.NET web site with WIF is very simple. Within Visual Studio you right-click the project, run an easy wizard in which you indicate from which federated partner you want to accept identities, and you are done. You even have the option to generate on the fly a local development STS which can be used if you do not have federated partners available at development time.

That simple procedure remains largely unchanged even when you are targeting Windows Azure as the deployment environment for your application: the few adjustments you need to apply are mainly related to the structural features of Windows Azure, such as the way in which X509 certificates are stored or how application URIs are handled across the different environments (Windows Azure compute emulator, Staging, Production).

In the following tasks, you will see how to create a Windows Azure WebRole, configure it to use a local development STS and modify the Windows Azure project in order to work in the Windows Azure compute emulator by still referencing the local development STS. Finally, you will publish the project in the cloud and see how the application still works with the local development STS when running in the staging and production environments.

This hands-on lab demonstrates the minimal integration scenario between WIF and Windows Azure. You can easily extend what you will learn here to more realistic scenarios, such as the case in which you want to reuse on-premises identities exposed via AD FS 2.0 (formerly known as “Geneva” Server). You will discover that the process is even simpler.

Figure 1

A summary of the steps followed by this exercise. You start by creating an ASP.NET website (RP) in a Windows Azure Web Role and an STS for it in the same Visual Studio solution and you establish trust between the two. Upon successful testing you publish & test the WebRole in staging and finally in production. The STS used at all stages is the one hosted by the local IIS: this is done to simplify the deployment of this guide on dev machines, but if you have a production STS available you can certainly use it in lieu of the test one.

Task 1 – Creating a Windows Azure project and Preparing it for Using Windows Identity Foundation

  1. Open Microsoft Visual Studio 2010 with administrator privileges. In Start | All Programs | Microsoft Visual Studio 2010, right-click Microsoft Visual Studio 2010 and select Run as administrator.
  2. In the File menu, choose New and then Project.
  3. In the New Project dialog, select Cloud in the Templates list.
  4. Select Windows Azure Project as project type.
  5. Choose a suitable name for your solution. Keep in mind that the name must be unique because it will be publicly visible when deployed to Windows Azure. Set the solution name “Begin” and the location to the %YourInstallationFolder%\Labs\WindowsAzureAndPassiveFederation\Source\Ex1-AzureFederatedAuthentication\ folder. Ensure Create directory for solution is checked and the framework is .NET Framework 4. Click OK to create the project.

    Figure 2

    Creating a new Windows Azure Project

    Note:
    Why do we require you to choose your own project name, instead of providing a sample solution?

    Every Windows Azure service is published on an URI of the form <projectname>.cloudapp.net.

    The string <projectname> must be unique, since it has to be resolvable on the public internet.

    For the first steps of this hand-on lab, you could technically use any project name you’d like, since all addresses will be resolved locally. You are forced to pick a unique name (and adjust the configurations accordingly) only at the moment in which you deploy your application in production.

    Note:
    The steps in this guide are more easily understood if the naming convention is coherent, hence we suggest you adhere to it at least the first time you go through it. If you want to adapt the instructions to the name you will choose, simply apply a Find & Replace against fabrikamair on the docx version of this document. When referring to the project name in procedure steps and figures, the hands-on uses the name fabrikamair. Substitute your own project name when following a procedure.

  6. In the New Windows Azure Project dialog, expand the Roles panel for Visual C#, select ASP.NET Web Role from the list of available roles and click the arrow (>) to add an instance of this role to the solution. Before closing the dialog, select the new role in the right panel, click the pencil icon and rename the role to FederatedIdentity_WebRole. Click OK to create the Windows Azure project solution.

    Figure 3

    Assigning roles to the Windows Azure project

  7. Generate a self-signed certificate for the application to use SSL. For your convenience, the lab material includes a script that performs the necessary actions. It creates the certificate using the subject you specify, installs it to the LocalMachine/Personal certificate store and adds the certificate to the LocalMachine/Trusted Root Certification Authorities store (to avoid the certificate error warning when browsing the site with IE). Open a Visual Studio command prompt as an administrator. To do this, open Start | All Programs | Microsoft Visual Studio 2010 | Visual Studio Tools, right-click Visual Studio Command Prompt (2010) and choose Run as administrator.
  8. Change the current directory to the %YourInstallationFolder%\Labs\WindowsAzureAndPassiveFederation\Source\Assets folder, where %YourInstallationFolder% is the installation folder of the lab, and execute the CreateCert.cmd script specifying the name of your project as a parameter.

    Note:
    VERY IMPORTANT! make sure to use lower casing for the certificate name.

    For example:

    Visual Studio Command Prompt

    CreateCert.cmd yourprojectname

    While running the script you will be asked to enter a password to secure your private key, type abc!123 and press OK.

    Figure 4

    Specifying a password to secure your private key

    Figure 5

    Specifying a password to secure your private key

    When you add the certificate to the Trusted Root Certification Authorities store, you are presented with a warning. Click Yes to install the certificate.

    Figure 6

    Adding a certificate as a trusted root

  9. Go to the Solution Explorer; navigate to <yourproject>/Roles/FederatedIdentity_WebRole. Right-click on it and choose Properties.

    Figure 7

    Modifying FederatedIdentity_Webrole properties

  10. Go to the Configuration Tab and ensure that the Full Trust option is set.

    Figure 8

    FederatedIdentity_WebRole is set to full trust so WIF work as expected

    Note:
    Why do you need to set .NET trust level to Full Trust?

    Windows Identity Foundation relies on Windows Communication Foundation (WCF) for handling various cryptography and protocol related operations. Today those parts of WCF require full trust to execute correctly, hence the Enable Full Trust requirement.

    Furthermore, the Windows Identity Foundation assemblies are not available in the Global Assembly Cache seen by Windows Azure projects (see below); hence partial trust execution would not be possible in any case.

  11. Go to the Certificates Tab and click on Add Certificate.

    Figure 9

    Selecting Add Certificate

  12. Type your <projectName> in the Name field and click on the Thumbprint column to select the cert you generated previously.

    Figure 10

    Selecting the certificate previously added

  13. In the Endpoints tab, add a new Https endpoint. Click Add Endpoint, and set the following values:

    • Name: HttpsIn
    • Type: Input
    • Protocol: https
    • Public Port: 8080
    • SSL Certificate Name: <yourprojectname>

    Figure 11

    Adding a Https endpoint

  14. Remove the HTTP endpoint. Select the existing “Endpoint1” and click Remove Endpoint.

    Figure 12

    Removing the Http endpoint

  15. Press Ctrl-S to save the properties.
  16. Go to Solution Explorer, right-click the FederatedIdentity_WebRole project and choose Add Reference. In the .NET tab, select Microsoft.IdentityModel and click OK.
  17. Go to the References folder for the FederatedIdentity_WebRole project, select Microsoft.IdentityModel. Press F4 to open the Properties window and set Copy Local to True and Specific Version to False.

    Note:
    Why do you need to set Copy Local to True for the reference to Microsoft.IdentityModel?Microsoft.IdentityModel is the main Windows Identity Foundation assembly. As mentioned above, such assembly is not available in the Global Assembly Cache that is visible to Windows Azure applications. By setting its Copy Local property to True, you ensure that the bits of the assembly will be included in the project package. Therefore, once you deploy it in the cloud, this will ensure that the WIF is deployed too and available to your application.

  18. Update the using statements into Default.aspx.cs in FederatedIdentity_WebRole.

    (Code Snippet – Federated Authentication for WebRole Guide – RP Usings)

    C#

    using System;
    FakePre-833eba54a4f0459699b6bf9fc29d7035-395531f678384bb9bf5ce20f5b40c0ecFakePre-e7f586efddb94d9eac6367583fa2516a-a901becac8b0417ab76d048def23070aFakePre-0e2e36d8d8c94b79aafe4828880e070d-3f73716ecc9f4de49322d454f54b4fa9FakePre-6b485f5c41934a2e95a9e880ecbf483b-fdc8489694a5404a92341bb6aba41985FakePre-70c95a89f5af43bf966cabcbd4192917-1a9390448ded4341aea0dd93c2e76a64using Microsoft.IdentityModel.Claims; using System.Threading;

  19. Insert the following code into the body of the Page_Load handler Default.aspx.cs in FederatedIdentity_WebRole.

    (Code Snippet – Federated Authentication for WebRole Guide – RP Page_Load Body)

    C#

    namespace FederatedIdentity_WebRole
    FakePre-78c87dddc3c9461c93173b412c515abf-f3003906d78648bd953850040f4fd1b7FakePre-c4450260b6e14f09afc1d28e1e5abb67-03451d85f3c64127809b2de867de2b65FakePre-24ef392415ef41f79a020021192e5209-4b79d1534d85455d889f953dd20be5c7FakePre-b5bc14ba95d34602ab138df6956066fc-d8e6c5ad6a9a48799b6058d1ab214d86FakePre-69e168f42b53434eb81249afb8cd34be-057a83fe58af418a8d931bfc66b6ac70 IClaimsPrincipal icp = Thread.CurrentPrincipal as IClaimsPrincipal; IClaimsIdentity ici = icp.Identity as IClaimsIdentity; Response.Write("Welcome to Fabrikamair <br/><br/>:Claims:<br/>"); foreach (Claim c in ici.Claims) Response.Write(c.ClaimType + "-" + c.Value + "<br/>");FakePre-e1efbe178b9e472ab3999dc1bb7a8a37-14eae427b8f34227817ac7aeca4944b7FakePre-f9bbe5e4f2c64fe9915f7510d276890b-e8bb4d49bd2141de893f67c955f2527dFakePre-cb3b33e30cfc4b31b854c1fc86d0c2e8-3ed18ae58f3d4d68b7b466f4528c2026

  20. Open the Default.aspx file and replace its content with the following.

    ASP.NET

    <%@ Page Title="Home Page" Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FederatedIdentity_WebRole._Default" %>

  21. In the FederetedIdentity_WebRole project, double-click the Global.asax file. Replace the current using statements with the following:

    (Code Snippet – Federated Authentication for WebRole Guide – RP Global.asax Using)

    C#

    using System; using System.Collections.Generic; using System.Web; using System.Text; using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Web; using Microsoft.IdentityModel.Web.Configuration;

  22. Add the WSFederationAuthenticationModule_RedirectingToIdentityProvider method as follows:

    (Code Snippet – Federated Authentication for WebRole Guide – RP Global.asax RedirectingToIdentityProvider)

    C#

    public class Global : System.Web.HttpApplication
    FakePre-4a92b828804c474098039311c88dadf7-3393b917fc0e4c6c9663163b63c3b636FakePre-0c83e0bbacad4b78840387c1dbbd771f-4837fde4d8d04c8bb92872bb40b6f2ff /// <summary> /// Retrieves the address that was used in the browser for accessing /// the web application, and injects it as WREPLY parameter in the /// request to the STS /// </summary> void WSFederationAuthenticationModule_RedirectingToIdentityProvider(object sender, RedirectingToIdentityProviderEventArgs e) { // // In the Windows Azure environment, build a wreply parameter for the SignIn request // that reflects the real address of the application. // HttpRequest request = HttpContext.Current.Request; Uri requestUrl = request.Url; StringBuilder wreply = new StringBuilder(); wreply.Append(requestUrl.Scheme); // e.g. "http" or "https" wreply.Append("://"); wreply.Append(request.Headers["Host"] ?? requestUrl.Authority); wreply.Append(request.ApplicationPath); if (!request.ApplicationPath.EndsWith("/")) wreply.Append("/"); e.SignInRequestMessage.Reply = wreply.ToString(); }FakePre-e32272e55229445d99e29fc40843a8c0-55149e5719b346e9986b939f9689a4faFakePre-9eaa2c836dab46afab518f733dc4c184-1db117a49a05492e8be8d9cb89758fb1FakePre-43eb956c4ede4ebab66e8fa782d87fb8-0a192ba2167b46909bf68ea27e66f15cFakePre-ed7c4af881ff489180b557822afcd1b7-24a85ec2828b492491d4a301c66673a5

    Note:
    What is the WSFederationAuthenticationModule_RedirectingToIdentityProvidermethod for?

    The federated sign on process implemented by WIF is based on the WS-Federation protocol. Unauthenticated users landing on the web site are redirected to the trusted STS for authentication and token issuance. The URI used for the redirection contains a number of parameters, mainly retrieved from the website Web.config: among those, there is the address to which the STS will have to redirect the user’s browser once successfully authenticated. In the default case, WIF retrieves that return address from the configuration settings generated by the Federation Utility wizard.

    In Windows Azure this approach would not work as is: an application hosted in Windows Azure will have a different URI depending on the environment in which it is hosted (Windows Azure compute emulator, staging, production) hence one would have to continuously change the values in the Web.config before deploying. In fact, even that strategy would not work in all cases since in the staging environment you learn what URI has been assigned to your app only AFTER you deployed the project.

    The current solution to this is finding out at runtime what the address of the app is, and injecting it in the request to the STS as wreply parameter. An STS receiving a wreply would use its value as the return address, hence decoupling your application from its address at deploy time.

    Of course, there are many security considerations to be made about this solution. To name one, this will often lead to a red address bar in Internet Explorer, since the subject of the certificate used to secure the website will match the URI only when the project is deployed in the production environment. Furthermore, this opens the door to redirect attacks that will have to be mitigated at the STS side.

    Why do you use the Host header instead of just getting the Uri from HttpContext.Current.Request.Url?

    Windows Azure uses various network artifacts in its infrastructure: as a result, the Url property of the current http request would contain ports that are not really meaningful outside Windows Azure internals and that would cause problems, for example mess up with session cookies. The code provided ensures that the URI in the browser address bar will be used.

  23. On the Global.asax.cs file, add the OnServiceConfigurationCreated method.

    (Code Snippet – Federated Authentication for WebRole Guide – RP Global.asax ServiceConfiguration_Created)

    C#

    public class Global : System.Web.HttpApplication
    FakePre-a0c2c7087e7240a49073b21d154944d5-07e92f48a5ef4f07a19bb820ffb18cb2FakePre-d8cf123b023a4387a58cffc03f473e31-abab178beebf4e0ca8f54b85fe93f572 void OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e) { // // Use the <serviceCertificate> to protect the cookies that are // sent to the client. // List<CookieTransform> sessionTransforms = new List<CookieTransform>(new CookieTransform[] { new DeflateCookieTransform(), new RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate), new RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate) }); SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly()); e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler); }FakePre-93eae0ef74ed4a58a2ee9f2a86d5f3b2-d43f9b75f1164c6c84dfab36e585a410FakePre-3ad1ff1f2f5447adb5add77e403fa7ba-b5cd940b940b4c088de5494f7607c4eb

    Note:
    What does ServiceConfigurationCreated do?

    By default WIF SessionTokens use DPAPI to protect the content of Cookies that it sends to the client, however DPAPI is not available in Windows Azure hence you must use an alternative mechanism. In this case, we rely on RsaEncryptionCookieTransform, which we use for encrypting the cookies with the same certificate we are using for SSL in our website.

  24. On the Global.asax.cs file, register the OnServiceConfigurationCreated handler in the Application_Start method.

    (Code Snippet – Federated Authentication for WebRole Guide – RP Global.asax Application_Start)

    C#

    ...
    FakePre-f5d33d109c644da49a19ff0a51cf6b3b-3402a6dc09b24b54bd5b32dcee70bd87FakePre-0ccb516d1fbf4525bbd6a78a8a45bb60-61defff5ed2445b2acb0202fb90da65aFakePre-cebcb33cc3fc477e80dfb6efeaa9a381-6e8f5e504634432a948f3d14928a9d2dFakePre-25056922ad6c475e9a7795c9ebb5a0f7-2565db2f7f804abda396e4ae56bf0430FakePre-80d947634959459ba27a8df717e18892-c143142bad85456cb3e22532671b073f FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;FakePre-8e4b48cae83c4933aa59d963f15a7663-8bd77a6834eb455abf01426c7deee494FakePre-4b1e0eb389d84b879e167e647df405fe-c1a23abe200e4f0f8abcdc9bd821488cFakePre-50cece703c034651aad1e9d76360c820-07e6f69cb95a4a798c7ecf5cb7bad086

Task 2 – Creating a Local Development STS

  1. Right-click on the solution and choose Add | New Web Site. Pick ASP.NET Security Token Service Web Site. Choose location HTTP, specify https://localhost/[yourprojectname]_sts to create it on your local IIS. Make sure that the Framework is .NET Framework 4 and click OK.

    Figure 13

    Creating your local STS website

  2. Open CustomSecurityTokenService.cs in https://localhost/[yourprojectname]_sts/App_Code. Add the following method to the CustomSecurityTokenService class, just above GetScope.

    (Code Snippet – Federated Authentication for WebRole Guide – STS ValidateReplyTo)

    C#

    public class CustomSecurityTokenService : SecurityTokenService
    FakePre-68e5dfdf6a4c460e95fbdb6d68f82f50-e5651f8674ff4cce921247bfb043f794FakePre-6e16bed31dae4065bb027670fa58f5ad-b808a61edfc3441eb1c16dae157847b9/// <summary> /// Validates replyTo and throws an exception if the replyTo refers to a /// RP that is not on the local machine or is not hosted in Windows Azure /// </summary> /// <param name="replyTo"> /// The replyTo parameter in the request that came in (RST) /// </param> void ValidateReplyTo(string replyTo) { // if ReplyTo is empty, we have nothing to validate. We will default // to AppliesTo, which is harder to compromise via redirect attack if (!String.IsNullOrEmpty(replyTo)) { string host = (new Uri(replyTo)).Host.ToLower(); if (!((host == "127.0.0.1") || (host == "localhost") || host.EndsWith(".cloudapp.net"))) { throw new InvalidRequestException( String.Format( "The host in the ReplyTo address {0} is not valid.", host)); } } }FakePre-960e2c650a6d44c7b4e1e3800e5b3810-7ca6d6f1910a412a9e49d6d11f19b0dfFakePre-5c3ba3dd429c4fd09465712267ed6377-2ed09c140d7341cdae5813d80d5f2d8cFakePre-69e29121daf54c019ab47d79b86274d6-da8fbab78d784d5089ba6a698366a988FakePre-22ed7e8506714a1a93ba07f2a87bee28-5e3bac4eafb04f49b8ce2f46b88425e8FakePre-1c5d405a20954cc687a3e09637634521-a414982c95b54c748e23ccca82a24dbeFakePre-2f8f6af9e95c4608b3aad5ae8278e276-633299b78e634d309f78c622e6afaa62FakePre-141e495fe97d455f845f0849f55a40dc-4c2fd24fab184d05a434c42849e68e03FakePre-4108d875af92440793a5c5172bcea913-db914b0dba66409f8139cf8f83005ec6FakePre-ca9b06390e264d75a950a560ea4a6613-a4081bc597df4112ad6e568297b02c9bFakePre-b15cc33ca9454b5e9db6c0e058a2a8f3-e23d0335ec5c44a294514866a83b0f64FakePre-d050142ae5f2477bb03a1174f9ebda41-acd81927c086430f948a5098f4ac4fa3FakePre-55e5b94d7f0349d09721089577f6f384-0cd522c4e48c4bd1a0fdea959d4b33a0FakePre-d0ab4f29c14d4ee295faf237564a6937-bf2a4920cc6043a2a625daa67d7aef85FakePre-9affb0e226344be1bc9bc606edf888a6-09f5096569fb4511b9cb98500f35f480

  3. At the beginning of GetScope, add a call to ValidateReplyTo that was added in the previous step.

    (Code Snippet – Federated Authentication for WebRole Guide – ValidateReplyTo Call)

    C#

    ...
    FakePre-3cdb2a297dd44cb3ba8f4708490142dc-46f0162c693c41cb9ac971f3987d2000FakePre-64b46747bf4e47f391afae71af63e61f-b9e254222e094d1db533a2d2f69680c4FakePre-aeab4348883847e488526b5306665e69-69a8b1c29bbc47faba66a483918376d5 ValidateReplyTo(request.ReplyTo);FakePre-888fd3469e954a5ab65bd57dfc8e821d-dd90508a079c407981b69390d735b869FakePre-f58d331c92354667bac3ac7a5ee32b11-fdfd88ca83044200ae421c410a09f85aFakePre-88f8e295dbb54119847467184b251211-8616ff5b767f4c3c8ab997896ed0cb22FakePre-1755fc92bffd4c70b3248c7c9870e2d8-dc8246f6898640788a5fc2f644bf48d2FakePre-a5ed7bb0444346b89cc7de63428b0475-949e50607cc3452e9fe367d0283a5157FakePre-00bfeb3a367442e0a37231687a64f808-2285c057e81d4f46af5709b7ea069f82FakePre-904126f1ca5642ad9411513ffe69b3e0-ace4496ac9484482af4e74947e7b09f0FakePre-5689d83b2a874efd903b23d5d6037913-a3036e9cfe004eedba7acf4bb3b0ee8fFakePre-c6b5491ab91b4ecab725eea615283cee-c42ec3e8313442e7838392683cdffed5

  4. At the end of GetScope, comment the current scope.ReplyToAddress assignment and replace it with the following code.

    (Code Snippet – Federated Authentication for WebRole Guide – STS Redirect to ReplyTo)

    C#

    protected override Scope GetScope( IClaimsPrincipal principal, RequestSecurityToken request )
    FakePre-15ffe8d48bd74277912732ee91701657-d963b7ac783a483f82d33fc686fcee40FakePre-501e72cc5b9c4ebcb86a42a83f757f8a-5b17111a7caf4414a2fc96eea9c9e00cFakePre-ee19a5fa30c641b5a9416b5c6d11f884-9dfb87997b7440e99ae8630c88e7a73eFakePre-0b1bffadd1dc4cad9cd6c469e8fbbdd5-141d089b2ad14275830cd855e44cc71eFakePre-227ec9657e4c46608b31c9f2c39117b8-6e50e4c5f54e4ad3b858cb56f0270e33scope.ReplyToAddress = String.IsNullOrEmpty(request.ReplyTo) ? scope.AppliesToAddress : request.ReplyTo;FakePre-52f9f659476e4bb9947e68d40ca2d3eb-deb296a2929547b9964647d4f6e0e4aeFakePre-c128eb698345487fa4421c691c9f8efa-a038e05a12cb4c7eb4ef7f5ad16d881eFakePre-077feb34be4e450dbd57b5f4e34c2d0f-da2885670ae944258d2a6bf4e2c714dd
    Note:
    Why do we make those changes to the default local STS auto-generated by the Federation Utility wizard?

    In Task 1, you modified the Global.asax of your application to ensure that it would send its actual URI to the STS, by storing it in the wreply parameter.

    The ValidateReplyTo ensures that the address in the wreply refers to an application on your local machine (as in the Windows Azure compute emulator case) or from a host ending with “.cloudapp.net” (as in the Windows Azure staging or production environments case). This mitigates redirection attacks, as it limits the accepted ReplyTo values to addresses of Windows Azure applications. Note that this check would prevent you from using a domain name not matching the Windows Azure schema; hence, if you plan to map Windows Azure applications through a custom domain, you will have to adjust the code accordingly.

    The assignment of scope.ReplyToAddress is modified to take the value of wreply, if present. If no wreply parameter is available in the request, the assignment will fold back to the default behavior (using the AppliesTo uri).

Task 3 – Establishing a Trust Relationship between the Web Role and the Development STS

  1. Go to Solution Explorer, right-click the FederatedIdentity_WebRole project and choose Add STS reference. Accept the proposed location for the application configuration file, set the Application URI to https://<yourProjectName>.cloudapp.net, where <yourProjectName> is the name chosen for your cloud project (e.g. https://fabrikamair.cloudapp.net/) and click Next.

    Figure 14

    The first screen of the Federation Utility wizard

  2. Select the option Use an existing STS, browse to %your inetpub folder%\wwwroot\<yourProjectName>_sts\FederationMetadata\2007-06\, select the file FederationMetadata.xml and click Next.

    Figure 15

    The second screen of the Federation Utility wizard

  3. Select the option No encryption and click Next.

    Figure 16

    Federation encryption setup screen

  4. Click Next.

    Figure 17

    Claim offered by the STS.

  5. On the summary page review the changes that will be made, and click Finish.

    Figure 18

    Summary

  6. Add the serviceCertificate element in the Web.config of the FederatedIdentity_WebRole project under microsoft.identityModel\service. You can find the corresponding thumbprint in the ServiceConfiguration.cscfg file.

    (Code Snippet – Federated Authentication for WebRole Guide – ServiceCertificate)

    XML

    <microsoft.identityModel>
    FakePre-7e31fa5c484e4699bae9cdc667b1e674-b17bf1d8c285447eaa5a4b905dc00050FakePre-356c4dc6ceb647e686269204581139f1-2346f1a4aad2460294f0500f1430198a <serviceCertificate> <certificateReference x509FindType="FindByThumbprint" findValue="[yourCorrespondingThumbprint]"/> </serviceCertificate>FakePre-f732627d7fc84b21b460d99d8ce0e37f-24e71be279cf4da8b009c3a748147417FakePre-f39d818f8df344f4b8ddc6b2f9032a92-7165846ba2f6409d920c15364aebfa20

  7. Add the certificateValidation element under the microsoft.identityModel\service element and set the certificateValidationMode attribute to None.

    (Code Snippet – Federated Authentication for WebRole Guide – CertificateValidation)

    XML

    <microsoft.identityModel>
    FakePre-8f37fdcc2de14929a6b5af79205d8c17-31bf47c1d246430581da29a1c50bd783FakePre-08c27becc3514c608ed6e988ec5699f1-8fc917caa91146ff8e44864a8426291dFakePre-3c687d5b7f2a452589edddb136e07730-5a4538a1c5ef4bb0a9413c88fc114bd6<certificateValidation certificateValidationMode="None"/>FakePre-4b8daf3b251b410481b3ad37bc838f5c-ae566f1c789d4bb8983704ee39cd77a0FakePre-2597de06dcac44149b341ae8fb888457-d4e9626ac033448ca923d03734cf4143

    Note:
     We expect the token we receive to be signed with the private key of the STS we trust. The Add STS Reference wizard we went through in steps 1 to 5 saved in the element issuerNameRegistry of web.config the thumbprint of the certificate of the STS we trust. Once we receive a token, WIF uses this information for:

    - Retrieving the corresponding certificate

    - Using the certificate for checking the token signature

    - Verifying that the signer was indeed listed in the issuerNameRegistry element, hence trusted

    In order to perform those operations, WIF can use the thumbprint for retrieving the bits of the STS certificate from the certificate store. However, certificate handling in Windows Azure requires extra operations, hence here we use an alternative method. Very often the request containing the token will also contain the bits of the certificate corresponding to the signature: this means that our application can use the thumbprint for retrieving the certificate from the request itself rather than relying on having the bits available locally. Setting the certificateValidationMode to None has the purpose of enabling the latter scenario.

    Note that the request does not have to contain the bits of the certificate, and for certain platforms this won’t be the default behavior: in those cases you will need to deploy in Windows Azure the public key (that is to say the certificate) of the STS as well, as shown in step 9 of task 5.

    ASP.NET by default validates all the POSTs done to the web application. This validation checks that the input is not dangerous. For instance, a piece of XML that is not encoded is considered dangerous for ASP.NET. A token is a piece of XML that is not encoded. To avoid getting an exception when the token is posted, you will add a class that will check if the input is a token. If it is, it will return true and will let the request to continue. If not, it will throw the regular "Apotentially dangerousRequest.Form value was detected..." exception.

  8. Add the SampleRequestValidator.cs file from the assets folder, to the FederatedIdentity_WebRole project.
  9. Open the Web.config file form the FederatedIdentity_WebRole project, add the httpRuntime element inside the system.web element and set the requestValidationType attribute to SampleRequestValidator.

    XML

    ...
    <httpRuntime requestValidationType="SampleRequestValidator" />FakePre-62b0e468064b41a8ace60965a581e78f-6103632443b44c5eb0bcbd0c53ede03a

Task 4 – Testing FabrikamAir in the Windows Azure compute emulator

In this task you will run the web application in the Windows Azure compute emulator, while the development STS we created in Task 2 will take care of authenticating users while running in the local IIS.

Figure 19

Local Deployment

  1. You are finally ready to test the application in the Windows Azure compute emulator. Set the cloud project as the startup project. To do this, in Solution Explorer, right-click the Windows Azure project and choose Set as StartUp Project.
  2. Press F5 to build and run the application. A browser page will open, pointing to https://127.0.0.1:8080. In the first screen, you will observe a certificate warning because the Windows Azure compute emulator uses an IP address for navigating to your application, while the certificate you are using refers to the address that the application will have once deployed in production in the cloud. Click Continue to this website.

    Figure 20

    Certificate Warning

    Note:
    The browser informs us that there is a discrepancy between the page address and the subject of the certificate used for the SSL binding: this is expected given the way in which Windows Azure compute emulator handles addresses

  3. You will be redirected to the local STS page that is hosted on your local IIS. Click Submit.

    Figure 21

    Authentication page

    Note:
    The default authentication page presented by local STS. Note the address bar: the STS still runs on the local IIS

  4. The STS issues the token and redirects to the Web Role application hosted in the Windows Azure compute emulator; WIF validates the token and grants the user access to the site. The red address bar once again indicates that the certificate you are using is already the one you will use in the cloud, hence the subject does not correspond to the URL shown in the browser. Close the browser and go back to Visual Studio.

    Figure 22

    Running Web application

    Note:
    The web application hosted in the Windows Azure compute emulator successfully authenticated the user, and correctly processed the incoming token as shown on the page. The address bar is red, as expected for applications in the Windows Azure compute emulator

Task 5 – Deploying CloudFabrikamAir in the Cloud and Testing it in Staging and Production

Now that you verified that the application works as expected in the Windows Azure compute emulator, you are ready to deploy it to the cloud and test it there.

Figure 23

Cloud Deployment

In this task you will publish your project to the staging environment, test it, and finally move it to the production environment

Note:
Please remember that to be able to deploy in the cloud you need an account on the Management Portal.

Steps of this task assume that you comply with the above requirement, that you have a subscription in place but that you did not create a service for this application yet.

  1. Navigate to https://windows.azure.com using a Web browser and sign in using your Windows Live ID.

    Figure 24

    Signing in to the Management Portal

  2. Create the compute component that executes the application code. Click Hosted Services on the left pane. Click on New Hosted Service button on the ribbon.

    Figure 25

    Creating a new hosted service

  3. In the Create a new Hosted Service dialog, select the subscription where you wish to create the service from the drop down list labeled Choose a subscription.

    Figure 26

    Choosing your subscription

  4. Enter a service name in the textbox labeled Enter a name for your service and choose its URL by entering a prefix in the textbox labeled Enter a URL prefix for your service, use same project name you used to generate the certificates in task 1.
  5. Select the option labeled Choose a region and then pick any of the available regions.
  6. Select the option labeled Do not Deploy.

    Note:
    While you can create and deploy your service to Windows Azure in a single operation by completing the Deployment Options section, for this hands-on lab, you will defer the deployment until the next steps.

    Figure 27

    Create a new hosted service dialog fulfilled

  7. Click OK to create the hosted service and then wait until the provisioning process completes.

    Figure 28

    Hosted service successfully created

  8. Before we can upload our package to the cloud, we need to ensure that our target environment will have all the certificates it needs for allowing our application to function as expected.

    Note:
     In step 11 of task 1 we picked a certificate from the local certificate store to act as the SSL certificate for our application. Now that we are preparing to deploy our application to the cloud, we need to ensure that the certificate and its private key will be available in our target deployment environment. Note that in this lab we do not take advantage of token encryption: if we did, we would have to decide if we want to decrypt tokens with the same certificate we use for SSL (in which case we would already be all set) or if we would want to use another one. In the latter case, we would need to repeat the steps 10 to 13 below for uploading the pfx encrypting certificate and its private key.

    Trust management via STS certificates requires some specific considerations: see the note in step 7 of task 3.

  9. Expand the project you have just created, select the Certificates folder and click Add Certificate on the Hosted Service Certificates ribbon.

    Figure 29

    Adding a certificate

  10. Click Browse to select the SSL certificate created on Task 1, Step 7 and 8.

    Figure 30

    Select the SSL certificate to upload

  11. Navigate to the folder where the certificate was created %YourInstallationFolder%\Labs\WindowsAzureAndPassiveFederation\Source\Assets\certs and select the file called <yourpProjectName>.cloudapp.net.pfx.

    Note:
    Make sure to select the .pfx file extension.

  12. Type the password for the private key of your certificate and click on Create.

    Figure 31

    Private key password

    Figure 32

    Uploaded certificate

  13. Now that the certificate was uploaded, we are ready to deploy the solution to Windows Azure. The certificates must be successfully deployed before uploading the solution, otherwise the solution deployment will fail. In Solution Explorer, right-click on the cloud project <yourprojectname>, and choose Publish.
  14. In the Publish Windows Azure Project dialog, choose Create Service Package Only, and click OK. In this process, Visual Studio will open two windows: one containing the package and configuration file; and a browser pointing to the provisioning page of the Management Portal (this may require you to authenticate using the Live ID account you registered with).

    Figure 33

    Publish Windows Azure Project dialog choosing the Create Service Package Only option

  15. Deploy your project to staging. Select your project and click the New Staging Deployment button on the New ribbon.

    Figure 34

    The hosted service as shown in the management portal

  16. In the Create a new Deployment dialog, you will be prompted to select the .cspkg and .cscfg files that you generated from Visual Studio in step 14 of this task: you can find them in the file system location indicated by the Windows Explorer window that opened when you published the package. Once both file paths have been selected, enter an arbitrary label for the deployment (e.g: the current date) in the Deployment name field, and click OK.

    Figure 35

    Deploying to staging

  17. If a warning popup appears, review the warnings and click Yes button to override them.
  18. The project has been deployed in the Staging environment and has been assigned an URL of the form <GUID>.cloudapp.net.

    Figure 36

    Package deployed in Staging and ready to run

  19. The application will spend some time Initializing (this might take 10 minutes at most). Once it goes into Ready status, click the DNS name link. A new browser will open, and you will get an error since the link is on http while you exposed only on https. Add the “s” to the protocol and the port number (i.e. https://5a90bc689ebd401c9c1d43b5cd200d7d.cloudapp.net:8080) in the address bar, and press ENTER. A certificate warning will be issued, since the staging URL, that contains a Guid, does not correspond to the certificate fabrikamair.cloudapp.net; you will be redirected to the development STS on your localhost; finally, you will land on the staging application where you will successfully authenticate.

    Figure 37

    The web application running in Staging environment

  20. Now you are finally ready to promote the deployment to Production. Ensure the current deployment is selected and click the Swap VIP button from the Deployments ribbon. Click OK on the Swap VIPs dialog.

    Figure 38

    Swap from Staging to Production

    Figure 39

    Swap VIPs dialog

  21. The project is now deployed and running in production. Click the DNS name link. You will need to manually add the “s” to the protocol and the port number (i.e. https://<yourProjectName>.cloudapp.net:8080) in the address bar, and press ENTER. This time you will not receive any certificate warning because the DNS name matches the certificate you uploaded. The browser will be redirected to the local STS running on your local IIS. Click Submit to authenticate. The home page of the website will show the claims issued by the STS.

    Figure 40

    The web application running in the Production environment with an HTTPS certificate