Export (0) Print
Expand All

6 – Securing Multi-Tenant Applications

This chapter examines topics related to security in multi-tenant applications. It focuses on issues that are specific to these types of applications, such as authenticating and authorizing different sets of users that authenticate with different types of identity and through trust relationships. The chapter also discusses how you can protect individual users’ data, and protect the session tokens they use when accessing your applications.

Protecting Users’ Data in Multi-Tenant Applications

In a multi-tenant application, tenants expect their data to be isolated from that of other tenants. A tenant will expect the application to behave as if that tenant is the sole user, and protect every tenant’s private data from any unauthorized access. As tenants, they expect to own their own data and have control over who has access to it.

Authentication

Your application must determine the identity of a user and verify that the user is a tenant of the application before granting access to any private data. It is your responsibility to provide an appropriate authentication mechanism for your multi-tenant application in Windows Azure, or to enable tenants to reuse their existing authentication mechanisms.

In a multi-tenant application, tenants may also want to control and manage their own users. For example, Adatum might want four of its employees to be able to create surveys using its subscription to the Tailspin Surveys application.

In addition to defining which of their employees should have access to the application, larger tenants may also want to use their own authentication mechanism. Their employees will already have a corporate account and, rather than having to remember a new set of credentials, they would like to be able to reuse their existing corporate credentials with the new multi-tenant web hosted service. You typically implement this type of scenario by using a claims-based approach that requires you to establish trust relationships between the parties involved. For more information, see the guide “A Guide to Claims-Based Identity and Access Control.”

Authorization

After your application has authenticated a request, it must authorize access to any resources used when it services the request. Some of the Windows Azure elements in your application may provide basic authorization services, but in most multi-tenant application scenarios you must implement the authorization yourself.

For example, there are no built-in authorization services in Windows Azure web and worker roles. If certain features implemented in your web and worker roles must be restricted to particular tenants, your application must perform the authorization based on the authenticated identity of the request.

To access Windows Azure storage services (tables, blobs, and queues), the calling code must know the storage account key for the specific storage account. Although it is unlikely that each tenant has its own storage account in a Windows Azure application, it may be the case that certain storage accounts should only be available to some tenants. Again it is your responsibility to ensure that the application code uses the correct storage account keys, and that you keep the storage account keys completely private. There is no reason for a tenant to know the storage account keys in a multi-tenant application unless the tenant is providing its own storage account.

If a tenant prefers to use a storage account in its own subscription, the tenant must provide you with the storage account keys so that the application can access the storage. It is then your responsibility to keep these keys safe on behalf of the tenant.

Hh534483.note(en-us,PandP.10).gifNote:
A person who gains unauthorized access to your Windows Azure account will be able to discover all of your storage account keys and access all of your data stored in Windows Azure storage. Once someone gains access to your Windows Azure subscription, there are no limits to what that person can access.

Windows Azure Service Bus adopts a different approach and provides an authorization service to manage operations such as sending messages. Windows Azure Access Control (ACS) performs the authentication either by validating a user name and password directly, or by delegating to an external identity provider such as the tenant’s Active Directory Federation Services (ADFS). For more information, see “Service Bus Authentication and Authorization with the Access Control Service.”

Protecting Sensitive Data

As an additional safeguard in a multi-tenant application you might consider encrypting each tenant’s data using a tenant specific key. This will help to ensure isolation if you can be sure that the keys used by each tenant are not revealed to anyone else.

You can use certificate based encryption in Windows Azure to strongly encrypt and decrypt data stored in Windows Azure table, blob, and queue storage; and data stored in Windows Azure SQL Database, SQL Server, and any other relational or non-relational database.

Hh534483.note(en-us,PandP.10).gifPoe Says:
Poe Certificate based encryption is a standard approach to encryption that uses a key pair. You use the public key to encrypt data and the private key to decrypt data. Typically, you use X-509 certificates for these tasks. Encrypting and decrypting data in Windows Azure is easy. The challenge in Windows Azure is storing your private key securely.

This section discusses how you decrypt data stored in Windows Azure from a worker or web role in your application. It does not address the scenario where you need to decrypt data stored in Windows Azure from a location outside of Windows Azure, such as in an on-premises application.

For sample code that illustrates how to perform encryption and decryption in a web or worker role, see the article “Using Certificate-Based Encryption in Windows Azure Applications.” That article also describes how you should manage the private key that enables your web or worker role to decrypt your data. The important points from the article about good practices for key management are as follows:

  • Only a small group of administrators (not developers or testers) should have access to the Windows Azure subscription that hosts the production application. These administrators are responsible for uploading a certificate that includes the private key used for decryption to the Windows Azure certificate store in the cloud service that hosts the production application.
  • Under no circumstances should this certificate be available or accessible to anyone else because the private key in this certificate enables you to decrypt the data. You should have secure processes that ensure this certificate is kept secure.
  • To enable a web or worker role to use the certificate for decryption you must add the certificate thumbprint to the service definition file. Typically, you add this thumbprint to the service definition file as part of an automated deployment process. Your application uses the thumbprint to locate the certificate in the Windows certificate store at runtime.

Following this approach by using the Windows Azure certificate store to store the certificate has a number of benefits:

  • If the processes to manage the certificate and the way it is uploaded to Windows Azure are correctly followed, you minimize the chance that this certificate will be available to anyone who might accidentally reveal it or use it maliciously.
  • There is no need for developers or testers to have access to the production certificate. They can use a different test certificate. All you need do to switch from using a test certificate to a production certificate is to update the thumbprint in the service definition file.
  • If someone gains unauthorized access to the Windows Azure subscription that hosts the production application, that person cannot gain access to the private key. You cannot export a service certificate from a Windows Azure cloud service, and when Windows Azure adds the certificate to the certificate store in the role instance it marks the private key as unavailable for export.

Although this approach protects your private key, there are still some potential vulnerabilities that you must guard against:

  • This approach requires you follow suitable procedures that ensure the certificate is kept secure while it is on-premises.
  • Although someone who gains unauthorized access to your Windows Azure subscription cannot access the private key, they can still run code that uses the private key to decrypt any encrypted data. A malicious user could deploy their own code that reads or modifies encrypted data, or a developer could write code that accidentally reveals or changes data in a way that the application is not supposed to do.

In general, the mitigations for these risks are clear auditable procedures for managing and monitoring your Windows Azure subscription, and testing your code to ensure that it behaves in the expected way.

In other scenarios you might need to encrypt and decrypt data in on-premises applications, but store and/or share it securely in Windows Azure. For example, one organization wants to store and publish encrypted data in Windows Azure and allow selected other organizations to download and decrypt the data. This type of scenario has a different key management problem that you can address using Windows Azure Trust Services. For more information, see “Learn More about Microsoft Codename Trust Services.”

Splitting Sensitive Data across Multiple Subscriptions

An additional technique to mitigate the risk that an attacker could discover sensitive data if your storage account keys are compromised is to split this data across two or more storage accounts. In this way, the sensitive data is not usable by the attacker unless the attacker gains access to two Windows Azure storage accounts by discovering two storage account keys.

For example, the credit card data associated with a user includes several pieces of information such as the user’s name, the credit card number, the three or four digit security number, and the validity dates. Typically, to make a payment with a credit card, you must have access to all of this information. If you store the credit card numbers held by your system in one storage account, and the remaining data in a different storage account, an attacker that compromises one of the storage accounts cannot access all the information needed to use the credit cards.

However, this approach only mitigates the risk that an unauthorized person gains access to your Windows Azure storage account keys. If someone gains unauthorized access to your Windows Azure subscription, he or she can discover all of the storage account keys in that subscription. Additionally, if that Windows Azure subscription uses data from a storage account in a different Windows Azure subscription the attacker could also discover that storage account key.

Hh534483.note(en-us,PandP.10).gifPoe Says:
Poe You should regularly change your storage account keys, especially for storage accounts that hold sensitive data.

Using Shared Access Signatures

In Windows Azure, knowledge of a storage account key grants full access to all of the data stored within that storage account. Therefore, if the code running a web or worker role can read a storage account key (typically from the service configuration file) it can access all the tables, blobs, and queues in that Windows Azure storage account.

Hh534483.note(en-us,PandP.10).gifBharath Says:
Bharath Blobs and blob containers can be configured for public read-only access so they can be read without requiring access to the storage account key.

In many applications, allowing the web and worker roles full access to data is acceptable; but in a multi-tenant application you may want to enforce isolation by ensuring that a task or operation can only access a single tenant’s data. One approach is to use a separate storage account for each tenant within the same Windows Azure subscription. However, Windows Azure limits the number of storage accounts that you can create within a single subscription, which limits the usefulness of this approach. The alternative is to use Shared Access Signatures (SAS).

A SAS is a unique and hard to guess URL that grants temporary access to a resource. For example, a SAS might grant read and write access to a specific blob for the next five minutes. To generate a SAS you must know the storage account key, but you can use the SAS without knowledge of the storage account key. Figure 1 shows how a worker role that acts as a gatekeeper can generate SAS URLs for other web and worker roles, granting them access to specific resources.

Figure 1 - Using SAS to access data in Windows Azure storage

Figure 1

Using SAS to access data in Windows Azure storage

The following list describes the steps in Figure 1 whereby the web role gains access to the contents of the blob containing Adatum’s data by using a SAS URL:

  1. The client browser sends a request to view Adatum’s data.
  2. The web role sends a request to the gatekeeper worker role for a SAS URL that will enable read only access to Adatum’s data. This data might be in table, blob, or queue storage.
  3. The gatekeeper worker role uses the storage account key to generate the SAS URL and returns it to the worker role.
  4. The web role uses the SAS URL when it queries for the Adatum data it needs to render the web page.
  5. The web role returns the page to the browser.

There are a number of points to note about this mechanism for accessing data in Windows Azure storage:

  • You should make sure that the web role doesn’t have access to the storage account key. In this scenario you are relying on the code in the web role to always access storage by requesting a SAS URL.
  • Without some additional layer of authentication and authorization, there is nothing to stop the web role asking for a SAS URL for any data.
  • You can create a SAS for an individual blob or a blob container. For table storage you can create a SAS for a table, or for a set of entities stored in the table and defined using a range of partition and row keys.
  • When you generate a SAS you can specify for how long it remains valid, and what types of access it supports (such as read, insert, update, and delete).

For more information see “Creating a Shared Access Signature” on MSDN and Chapter 5, “Executing Background Tasks,” in the guide “Moving Applications to the Cloud."

Hh534483.note(en-us,PandP.10).gifJana Says:
Jana You can also use a SAS to expose private blobs directly to a client. This is typically used to enhance the scalability of a solution by enabling a browser to display the content of a private blob. For more information, see Chapter 5, “Maximizing Availability, Scalability, and Elasticity.”

Goals and Requirements

This section describes the goals and requirements for security that Tailspin has for the Surveys application.

Authentication and Authorization

The Tailspin Surveys application targets a wide range of subscribers, from individuals to large enterprises. All subscribers of the Surveys application will require authentication and authorization services to control access to their survey definitions and results, but they will want to implement these services differently.

Hh534483.note(en-us,PandP.10).gifNote:
For more information about this scenario, see Chapter 6, “Federated Identity with Multiple Partners,” in the guide “A Guide to Claims-Based Identity and Access Control.”

Privacy

Tailspin wants to ensure that users’ privacy is maintained. The Tailspin Surveys application should not leave any sensitive data on the client machine after a user has accessed any of the Tailspin Surveys websites. The private tenant website uses cookies to track sessions, and Tailspin wants to continue to use cookies. Therefore it has decided to encrypt the contents of these cookies in order to protect the privacy of its users.

Overview of the Solution

This section describes the approach taken by Tailspin to meet the goals and requirements that relate to security in the Surveys application.

Identity Scenarios in the Surveys Application

Tailspin has identified three different identity scenarios that the Surveys application must support:

  • Organizations may want to integrate their existing identity infrastructure and be able to manage access to the Surveys application themselves in order to include Surveys as a part of the Single Sign-On (SSO) experience for their employees.
  • Smaller organizations may require Tailspin to provide a complete identity system because they are not able to integrate their existing systems with Tailspin.
  • Individuals and small organizations may want to re-use an existing identity, such as their Microsoft account, Open ID credentials, or an account with other social identity providers.
Hh534483.note(en-us,PandP.10).gifBharath Says:
Bharath Tailspin uses a claims-based infrastructure to provide the flexibility it needs to support its diverse subscriber base.

To support these scenarios Tailspin uses the WS-Federation protocol to implement identity federation. The following diagrams describe how the authentication and authorization process works for each of the three identity scenarios Tailspin identified.

Hh534483.note(en-us,PandP.10).gifNote:
The three scenarios are all claims based and share the same core identity infrastructure. The only difference is the source of the original claims.

Integrating a Subscribers Own Identity Mechanism

Figure 2 - How users at a large enterprise subscriber access the Surveys application

Figure 2

How users at a large enterprise subscriber access the Surveys application

In the scenario shown in Figure 2 users at Adatum, a large enterprise subscriber, authenticate with Adatum's own identity provider (step 1), in this case Active Directory Federation Services (ADFS). After successfully authenticating an Adatum user, ADFS issues a token. The client browser forwards the token to the Tailspin federation provider that trusts tokens issued by Adatum's ADFS (step 2) and, if necessary, performs a transformation on the Adatum claims in the token into claims that Tailspin Surveys recognizes (step 3) before returning a new token to the client browser. The Tailspin Surveys application trusts tokens issued by the Tailspin federation provider and uses the claims in the token to apply authorization rules (step 4).

Users at Adatum will not need to remember separate credentials to access the Surveys application, and an administrator at Adatum will be able to configure in Adatum’s own ADFS the list of Adatum users that can access the Surveys application.

Hh534483.note(en-us,PandP.10).gifPoe Says:
Poe All of the token issuing and passing is handled automatically through a sequence of browser redirects. The user simply navigates to the Tailspin Surveys website.

Providing an Identity Mechanism for Small Organizations

Figure 3 - How users at a small subscriber access the Surveys application

Figure 3

How users at a small subscriber access the Surveys application

In the scenario shown in Figure 3 users at Fabrikam, a smaller company, authenticate with the Tailspin identity provider (step 1) because their own Active Directory can’t issue tokens that will be understood by the Tailspin federation provider. If the Tailspin identity provider can validate the credentials, it returns a token to the client browser that includes claims such as the user’s identity and the tenant’s identity. The client browser forwards the token to the Tailspin federation provider that trusts tokens issued by Tailspin identity provider (step 2) and, if necessary, performs a transformation on the Tailspin identity provider claims in the token into claims that Tailspin Surveys recognizes (step 3) before returning a new token to the client browser. The Tailspin Surveys application trusts tokens issued by the Tailspin federation provider and uses the claims in the token to apply authorization rules (step 4).

Other than the choice of identity provider, this approach is the same as that used for Adatum. The downside of this approach for Fabrikam users is that they must memorize separate credentials just to access the Surveys application. Fabrikam users will be prompted for their credentials when they navigate to the Tailspin Surveys application. Tailspin must also provide a way to manage the user accounts that the Tailspin identity provider uses.

Tailspin plans to implement this scenario by using an ASP.NET membership provider to manage the user accounts, and use a security token service (STS) that integrates with the membership provider.

Hh534483.note(en-us,PandP.10).gifNote:
For guidance on how to implement this scenario take a look at the thinktecture IdentityServer project on CodePlex.

Integrating with Social Identity Providers

Figure 4 - How an individual subscriber accesses the Surveys application

Figure 4

How an individual subscriber accesses the Surveys application

For individual users the process is again very similar. In the scenario shown in Figure 4 the Tailspin federation provider is configured to trust tokens issued by a third-party identity provider, such as an identity provider that authenticates a Microsoft account or OpenID credentials. Tailspin plans to use Windows Azure Access Control to implement this scenario.

When an individual user authenticates with his or her chosen identity provider (step 1), the identity provider returns a token to the client browser that includes claims such as the user’s identity. The client browser forwards the token to the Tailspin federation provider that trusts tokens issued by the third-party provider (step 2) and, if necessary, performs a transformation on the claims in the token into claims that Tailspin Surveys recognizes (step 3) before returning a new token to the client browser. The Tailspin Surveys application trusts tokens issued by the Tailspin federation provider and uses the claims in the token to apply authorization rules (step 4). When the user tries to access their surveys, the application will redirect them to their external identity provider for authentication.

Hh534483.note(en-us,PandP.10).gifNote:
For additional guidance on how to implement this scenario, see the chapter “Federated Identity with Multiple Partners and Windows Azure Access Control Service” in the guide “A Guide to Claims-Based Identity and Access Control.”

Windows Azure Access Control Service and Windows Azure Active Directory

Although the Tailspin Surveys sample solution uses Windows Identity Foundation (WIF) to implement a WS-Federation compliant federation provider (see the TailSpin.SimulatedIssuer project in the solution), a production deployment would use a real federation provider such as Active Directory Federation Services (ADFS), Windows Azure Access Control, or Windows Azure Active Directory.

Windows Azure Access Control is one element of Windows Azure Active Directory. It enables you to move authentication and authorization logic out of your code and into a separate cloud-based service. Access Control can integrate with other standards based identity providers, and can implement a claims transformation process using declarative rules that convert the claims issued by the tenant’s issuer, third-party issuer, or Tailspin’s own issuer into claims understood by the Tailspin Surveys application. Access Control can also perform the protocol conversion required to support many third-party issuers.

Windows Azure Active Directory includes the Windows Azure Authentication Library that allows developers to focus on business logic in their applications, ignore most protocol details, and easily secure resources without being an expert on security. Windows Azure Active Directory also includes a REST API that enables programmatic access to Access Control and the Authentication Library.

Hh534483.note(en-us,PandP.10).gifNote:
For more information see “Windows Azure Active Directory.” For more information about using Access Control see the related patterns & practices “Claims Based Identity & Access Control Guide.

Configuring Identity Federation for Tenants

When a new tenant subscribes to the Tailspin Surveys service, it has the option to use its own identity provider instead of Tailspin’s to authenticate its users when accessing the private tenant web site. In the sample application code, the Join screen is currently mocked out to illustrate the information that a tenant would need to provide in order to establish the federated identity environment described earlier in this chapter.

Hh534483.note(en-us,PandP.10).gifPoe Says:
Poe In a real application this screen would enable a tenant to select between the three identity scenarios supported by Tailspin Surveys. For tenants who chose to use the Tailspin identity provider you would have a registered members database and each tenant would be allowed to add and remove members authorized to use the subscription.

However, the sample application does allow a Tailspin administrator to add a new federated identity provider on behalf of a tenant on the Manage screen. Tailspin Surveys then saves the configuration data in Windows Azure blob storage as part of the tenant configuration information. The following table describes the information used to configure identity federation for a tenant.

Value

Description

Example

Identifier

Tailspin’s identity provider uses this value to recognize claims sent from a trusted identity provider.

http://adatum/trust

Sign-in URL

The address of the tenant’s trusted identity provider.

https://localhost/Adatum.SimulatedIssuer.v2/

Thumbprint

The thumbprint of the certificate used by the tenant’s identity provider to sign the claims it sends to Tailspin.

f260042d59e14817984c6183fbc6bfc71baf5462

Admin Claim Type

The claim type that the tenant uses to identify users with administrative privileges in their Tailspin Surveys subscription. This is used to map the tenant’s claim type to the Tailspin Role claim type.

http://schemas.xmlsoap.org/claims/group

Admin Claim Value

The value of the administrator claim type that has administrative privileges in the tenant’s Tailspin Surveys subscription. This value is mapped to the SurveyAdministrator role in Tailspin Surveys.

Marketing Managers


Encrypting Session Tokens in a Windows Azure Application

The Tailspin Surveys tenant web site uses sessions to maintain the list of questions that a tenant adds when designing a new survey. The website uses a cookie to track requests that belong to the current user’s session. Part of Tailspin’s security requirements is that the application should encrypt cookies so that there is no usable information left on the client machine.

Tailspin plans to use at least two instances of the web role that hosts the tenant website in order to make the site more available. Therefore, the encryption mechanism that the application uses to encrypt the cookies must be web farm friendly. A cookie that one role instance creates and encrypts must be readable by all other instances.

By default, when you use the Windows Identity Foundation (WIF) framework to manage your identity infrastructure, it encrypts the contents of the cookies that it sends to the client by using the Windows Data Protection API (DPAPI). Using DPAPI for cookie encryption is not a workable solution for an application that has multiple role instances because each role instance will use a different encryption key, and the Windows Azure load balancer could route a request to any instance. You must use an encryption mechanism such as RSA, which uses a key that two or more instances can share.

Inside the Implementation

Now is a good time to walk through some of the code in the Tailspin Surveys application in more detail. As you go through this section, you may want to download the Visual Studio solution for the Tailspin Surveys application from http://wag.codeplex.com/.

Using Windows Identity Foundation

Figure 5 will help you to keep track of how the WIF authentication process works as you look at the detailed description and code samples later in this chapter.

Figure 5 - Federation with multiple partners sequence diagram

Figure 5

Federation with multiple partners sequence diagram
Hh534483.note(en-us,PandP.10).gifJana Says:
Jana The sequence shown in Figure 5 applies to all three authentication and identity scenarios described earlier in this chapter. In the context of Figure 5, the Issuer is the Tailspin federation provider, so step 3 includes redirecting to another issuer to handle the authentication.

For clarity, Figure 5 shows the “logical” sequence, not the “physical” sequence. Wherever the diagram has an arrow with a Redirect label, this actually sends a redirect response back to the browser, and the browser then sends a request to wherever the redirect message specifies.

The following describes the steps illustrated in Figure 5:

  1. The process starts when an unauthenticated user sends a request for a protected resource; for example the adatum/surveys page. This invokes a method in the SurveysController class.
  2. The AuthenticateAndAuthorizeTenant attribute that extends the AuthenticateAndAuthorizeRole attribute and implements the MVC IAuthorizationFilter interface is applied to this controller class. Because the user has not yet been authenticated, this will redirect the user to the Tailspin federation provider at https://localhost/TailSpin.SimulatedIssuer with the following query string parameter values:

    wa. Wsignin1.0

    wtrealm. https://tailspin.com

    wctx. https://127.0.0.1:444/survey/adatum

    whr. http://adatum/trust

    wreply. https://127.0.0.1:444/federationresult

    The following code example shows the BuildSignInMessage method in the AuthenticateAndAuthorizeTenantAttribute class that builds the query string.

    protected override WSFederationMessage
      BuildSignInMessage(AuthorizationContext context, 
                         Uri replyUrl)
    {
      var tenant =
        (context.Controller as TenantController).Tenant;
    
      var fam = FederatedAuthentication
                .WSFederationAuthenticationModule;
      var signIn = new SignInRequestMessage
                     (new Uri(fam.Issuer), fam.Realm)
      {
        Context = AuthenticateAndAuthorizeRoleAttribute
          .GetReturnUrl(context.RequestContext,
                        RequestAppendAttribute.RawUrl, 
                        null).ToString(),
        HomeRealm = SubscriptionKind.Premium
          .Equals(tenant.SubscriptionKind)
          ? tenant.IssuerIdentifier 
          ?? Tailspin.Federation.HomeRealm + "/"
          + (context.Controller 
             as TenantController).Tenant.Name
          : Tailspin.Federation.HomeRealm + "/"
          + (context.Controller 
             as TenantController).Tenant.Name,
        Reply = replyUrl.ToString()
      };
    
      return signIn;
    }
    
  3. The Issuer, in this case the Tailspin simulated issuer, authenticates the user and generates a token with the requested claims. In the Tailspin scenario, the Tailspin federation provider uses the value of the whr parameter to delegate the authentication to another issuer; in this example, the Adatum issuer. If necessary, the Tailspin federation issuer can transform the claims it receives from the issuer into claims that the Tailspin Surveys application understands. The following code from the FederationSecurityTokenService class shows how the Tailspin simulated issuer transforms the Group claims in the token from the Adatum issuer.
    protected override IClaimsIdentity
      GetOutputClaimsIdentity(IClaimsPrincipal principal,
                            RequestSecurityToken request,
                            Scope scope)
    {
      ...
    
      var input = principal.Identity as ClaimsIdentity;
    
      var tenant = this.tenantStore.GetTenant
        (input.Claims.First().Issuer);
    
      ...
    
      var output = new ClaimsIdentity();
    
      CopyClaims(input, 
        new[] { WSIdentityConstants.ClaimTypes.Name },
        output);
      TransformClaims(input, tenant.ClaimType,
        tenant.ClaimValue, ClaimTypes.Role,
        Tailspin.Roles.SurveyAdministrator, output);
      output.Claims.Add(
        new Claim(Tailspin.ClaimTypes.Tenant,
                  tenant.Name));
    
      return output;
    }
    
    Hh534483.note(en-us,PandP.10).gifNote:
    This example shows how the claim the tenant identified as granting access to the subscription is mapped to the Tailspin Role claim with a value of SurveyAdministrator.

  4. The Tailspin federation provider then posts the token and the value of the wctx parameter (https://127.0.0.1:444/survey/adatum) back to the address in the wreply parameter (https://127.0.0.1:444/federationresult). This address is another MVC controller, which does not have the AuthenticateAndAuthorizeTenantAttribute attribute applied. The following code example shows the FederationResult method in the ClaimsAuthenticationController controller.
    [RequireHttps]
    public class ClaimsAuthenticationController 
      : Controller
    {
      [ValidateInput(false)]
      [HttpPost]
      public ActionResult FederationResult()
      {
        var fam = FederatedAuthentication
                 .WSFederationAuthenticationModule;
        if (fam.CanReadSignInResponse(
          System.Web.HttpContext.Current.Request, true))
        {
          string returnUrl = GetReturnUrlFromCtx();
          return this.Redirect(returnUrl);
        }
        return this.RedirectToAction(
                    "Index", "OnBoarding");
      }
    
  5. The WS Federation Authentication Module validates the token by calling the CanReadSignInResponse method.
  6. The ClaimsAuthenticationController controller retrieves the value of the original wctx parameter and issues a redirect to that address.
  7. This time, when the request for the adatum/surveys page goes through the AuthenticateAndAuthorizeTenantAttribute filter, the user has been authenticated. The following code example from the AuthenticateAndAuthorizeRoleAttribute class shows how the filter checks whether the user is authenticated.
    public void OnAuthorization(
                    AuthorizationContext filterContext)
    {
      ...
    
      if (!filterContext.HttpContext.User
           .Identity.IsAuthenticated)
      {
        AuthenticateUser(filterContext);
      }
      else
      {
        this.AuthorizeUser(filterContext);
      }
      ...
    }
    
  8. The AuthenticateAndAuthorizeTenantAttribute filter then applies any authorization rules. In the Tailspin Surveys application the AuthorizeUser method verifies that the user is a member of one of the roles listed where the AuthenticateAndAuthorizeTenant attribute decorates the MVC controller, as shown in the following code example.
    [AuthenticateAndAuthorizeTenant(
                    Roles = "Survey Administrator")]
    [RequireHttps]
    public class SurveysController : TenantController
    {
      ...
    }
    
  9. Finally, the controller method executes.

Protecting Session Tokens in Windows Azure

The following code example shows how the Surveys application configures the session security token handler to use RSA encryption instead of the default DPAPI encryption. This enables Tailspin to deploy multiple instances of the web role that can use the shared key.

Hh534483.note(en-us,PandP.10).gifJana Says:
Jana An ASP.NET web application running in an on-premises web farm would also need to use shared key encryption instead of DPAPI.

Before Tailspin deploys the Surveys application to Windows Azure it must upload the shared encryption key to the Windows Azure certificate store. Windows Azure stores the key as part of the cloud service definition, and it is accessible to all the roles and role instances deployed to the cloud service.

Hh534483.note(en-us,PandP.10).gifNote:
You can create an X-509 certificate that is suitable for use with the RSA encryption algorithm by using the makecert tool. For more information, see “How to Create a Certificate for a Role.” For more information about uploading a key to the Windows Azure certificate store, see “How to Add a New Certificate to the Certificate Store.”

The following code from the Global.asax file in the Tailspin.Web project shows how the application loads the certificate it will use for encrypting and decrypting the session cookie from the certificate store in the cloud service. The application identifies the certificate from the thumbprint in the serviceCertificate element in the Web.config file.

private void OnServiceConfigurationCreated(object sender, 
    ServiceConfigurationCreatedEventArgs e)
{
  var sessionTransforms =
      new List<CookieTransform>(
          new CookieTransform[] 
          {
            new DeflateCookieTransform(), 
            new RsaEncryptionCookieTransform(
              e.ServiceConfiguration.ServiceCertificate),
            new RsaSignatureCookieTransform(
              e.ServiceConfiguration.ServiceCertificate)  
          });
  var sessionHandler = new SessionSecurityTokenHandler(
                           sessionTransforms.AsReadOnly());
  e.ServiceConfiguration.SecurityTokenHandlers
                        .AddOrReplace(sessionHandler);
}

The Application_Start method in the Global.asax.cs file hooks up this event handler to the FederatedAuthentication module.

Hh534483.note(en-us,PandP.10).gifNote:
For more information about the DPAPI, see “Windows Data Protection” on MSDN.

More Information

For more information about the claims-based authentication and authorization model used in the Surveys application see Chapter 6, “Federated Identity with Multiple Partners,” of the guide “A Guide to Claims-Based Identity and Access Control.”

For a walkthrough of how to secure an ASP.NET site on Windows Azure with WIF, see “Exercise 1: Enabling Federated Authentication for ASP.NET applications in Windows Azure” on Channel 9.

For more information about using forms authentication with your Windows Azure application, see “Real World: ASP.NET Forms-Based Authentication Models for Windows Azure.”

Show:
© 2014 Microsoft