Recently I wrote a WCF service that fronted an on-premises SQL Server database for an MVC application running in a Window Azure Web Role. There are a number of ways I could have approached this scenario; I decided to use the netTcpRelayBinding via the Windows Azure Service Bus for the following reasons:

  • I needed optimal performance (i.e. TCP over HTTP).
  • I wanted to reuse existing connections (rather than opening many connections).
  • I didn’t want to open up ports in my firewall (inbound or outbound).

Based on these requirements, the Service Bus is almost a no brainer. The Service Bus provides both messaging and connectivity capabilities, the latter of which provide a nice way to build loosely coupled applications in hybrid scenarios (i.e. cloud + on-premises).

I dove right in and wrote the following code:

public static IEnumerable<Customer> GetCustomers()
{
    Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", 
        "MYSERVICENAMESPACE", "Customer");
    var customersChannelFactory = new ChannelFactory<ICustomerChannel>(
        "RelayEndpoint", new EndpointAddress(serviceUri));
    var customersChannel = customersChannelFactory.CreateChannel();
    customersChannel.Open();

    return customersChannel.GetCustomers();
}

(I put much of the binding, client, and endpoint behaviors in the Web.Config.)

This code works but has problems. The channel to the Service Bus will open every time the service is called, resulting in suboptimal performance. To make this more efficient I decided to make the ChannelFactory and Channel variables statics so that I could reuse the channel if it had already been opened.

static ChannelFactory<ICustomerChannel> customersChannelFactory;
static ICustomerChannel customersChannel;

public static IEnumerable<Customer> GetCustomers()
{
    if (customersChannelFactory == null || customersChannel == null)
    {
        Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", 
            "MYSERVICENAMESPACE", "Customer");
        customersChannelFactory = new ChannelFactory<ICustomerChannel>(
            "RelayEndpoint", new EndpointAddress(serviceUri));
        customersChannel = customersChannelFactory.CreateChannel();
        customersChannel.Open();
    }

    return customersChannel.GetCustomers();
}

This updated does a good job of improving the performance of the service call but has it’s own problems. When you create a Channel through the ChannelFactory your channel can enter a faulted state – with the Service Bus there are a number of ways that this can occur (in my testing it was because I often stopped/started the service host). When this happens the WCF communication static must be reset by recreating the client channel.

Finding an efficient – and somewhat elegant – way of handling the faulted state proved to be a fun challenge. Fortunately, I received a lot of help from folks on the Service Bus team.

In the end I went with the following code:

static ChannelFactory<ICustomerChannel> customersChannelFactory;
static ICustomerChannel customersChannel;

public static IEnumerable<Customer> GetCustomers()
{
    List<Customer> customers = null;

    if (customersChannelFactory == null)
    {
        Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", 
            "MYSERVICENAMESPACE", "Customer");
        customersChannelFactory = new ChannelFactory<ICustomerChannel>(
            "RelayEndpoint", new EndpointAddress(serviceUri));
    }

    int tries = 0;
    while (tries++ < 3)
    {
        try
        {
            if (customersChannel == null)
            {
                customersChannel = customersChannelFactory.CreateChannel();
                customersChannel.Open();
            }

            return customersChannel.GetCustomers();
        }
        catch (CommunicationException)
        {
            customersChannel.Abort();
            customersChannel = null;
        }
    }

    return customers;
}

More verbose but much, much better.

The key is correctly handling the CommunicationException, aborting the channel, and setting the channel to null. Since we have retry logic via the while loop it will try again, determine that the channel is null, and re-open the channel.

There are certainly other ways to do this correctly. For example, you could decide to create a Faulted event handler.

I hope this helps!

The Windows Azure AppFabric Service Bus uses a class called TransportClientEndpointBehavior to specify the credentials for a particular endpoint.  There are four options available to you: Unauthenticated, SimpleWebToken, SharedSecret, and SAML.  For details, take a look at the CredentialType member.  The first three are pretty well described and documented – in fact, if you’ve spent any time at all looking at the Service Bus, you’ve probably seen the following code:

SharedSecret Credential Type
  1. TransportClientEndpointBehavior relayCredentials = new TransportClientEndpointBehavior();
  2. relayCredentials.CredentialType = TransportClientCredentialType.SharedSecret;
  3. relayCredentials.Credentials.SharedSecret.IssuerName = issuerName;
  4. relayCredentials.Credentials.SharedSecret.IssuerSecret = issuerSecret;

This code specifies that the client credential is provided as a self-issued shared secret that is registered and managed by Access Control, along with the Issuer Name and Issuer Secret that you can grab (or generate) in the AppFabric portal. Quick and easy, but only marginally better than a username/password.

The use of a SAML token is more interesting, and in fact lately I’ve seen a number of requests for a sample.  Unfortunately, it doesn’t appear that anyone has ever created a sample on how this should work.  It’s one thing to say that the above code would change to the following …

Saml Credential Type
  1. TransportClientEndpointBehavior samlCredentials = new TransportClientEndpointBehavior();
  2. samlCredentials.CredentialType = TransportClientCredentialType.Saml;

… and something else to provide a sample that works.  What makes this challenging is the creation of the SAML token – this is a complex process, and difficult to setup, test, or fake.  Fortunately for you, I have put together a sample on how to use a SAML token as the CredentialType of the TransportClientEndpointBehavior.

DISCLAIMER: I am not an identity expert.  You should look to people like Justin Smith, Vittorio Bertocci, Hervey Wilson, and Maciej ("Ski") Skierkowski’s for specific identity guidance.  I’m simply leveraging much of the material, samples, and code they’ve written in order to enable this particular scenario.

In order to get this sample to work I’ve a number of frameworks.  You’ll need to download and install these to get everything to work properly.

  • .NET 4.0 Framework – I’ve only tested this with Visual Studio 2010 and the .NET 4.0 Framework.
  • Windows Azure AppFabric SDK V1.0 – this SDK provides you with all the assemblies you’ll need in order to use the Service Bus.
  • Windows Identity Foundation – WIF allows you to externalize use access from applications via claims (which is what we want to do).
  • Windows Identity Foundation SDK – the WIF SDK provides you with templates and code samples to get going.  Technically I don’t think we’re using this, but I have it installed and I’m not going to uninstall it to test.

I also used a number of samples in order to build this sample.  You won’t need to download and install these in order to use this sample – I’m providing the source of the modified code below – but you might want to take a look at them anyways.

Okay, now that we’ve got the various components and samples described, let’s get to the sample.

Overview

When I first started writing this post, I thought it’d be short and sweet.  As you can see, it’s anything but.  However, when you look through everything, I think you’ll see that there’s quite a bit to this sample.

There are three major pieces in this sample:

  1. Using a security token service (STS) to generate a SAML token.
  2. Configuring the Access Control service to accept the SAML token and authorize our WCF service to Send or Listen across the Service Bus.
  3. Modifying the EchoSample WCF service to get a SAML token and send it to Access Control.

Let’s walk through the pieces.

The Security Token Service

Remember my disclaimer above?  Since I’m not an identity guy, I decided to use a tool built by an identity guy to act as my STS.  Vittorio has created a fabulous tool called SelfSTS, which exposes a minimal WS-Federation STS endpoint.  In the Fabrikam Shipping SaaS Demo Source Code, he provided an updated version of the SelfSTS tool that will also issue via WS-Trust, along with a sample on how to acquire the token and send it to ACS.

If you download FabrikamShippingSaaS and install it in the default location, you can find these two assets in the following locations:

  • Updated SelfSTS: C:FabrikamShippingSaaSassetsSelfSTSSelfSTS.sln
  • Token acquisition and ACS submittal example: C:FabrikamShippingSaaScodeTestClient.sln

Definitely take a look at these resources.  I highly encourage you to use these as much and as often as you like – the SelfSTS tool is invaluable when working with Access Control and WIF.  In the TestClient solution, the method we’re most interested in is the GetSAMLToken method found in the Program.cs file.  Take a look at it, but realize that we’re going to make a few changes to it for our example.

For the purposes of this sample, I took the SelfSTS project and included it in the EchoSampleSAML solution that you can find below.  The only update I made to the tool was to extract a method I called Start – which encapsulates all of the logic needed to start the tool – and call it in the Main method.

Go ahead and run the SelfSTS project in the EchoSampleSAML solution below by right-clicking and choosing Debug –> Start New Instance.  It looks like this:

SelfSTS

There are two items that we’ll leverage below:

Quickly stop the SelfSTS and click “Edit Claim Types and Values”.

Edit Claims

These are the claims that the SelfSTS will return.  I’ve highlighted “joe” because we’re going to use this claim below when configuring Access Control.  Make a mental note, because I want you to be aware of where “joe” comes from.

Go ahead and keep this tool running the entire time – you’ll leverage it throughout this process.

Configuring Access Control

The production Access Control services does not provide a UI in the portal to configure issuers and rules.  Consequently, we’ll use the AcmBrowser tool found within the Windows Azure AppFabric SDK Samples.  Depending on where you unzip the samples, you’ll find it here:

    C:WindowsAzureAppFabricSDKSamples_V1.0-CSAccessControlExploringFeaturesManagementAcmBrowser

When you open the solution you’ll have to upgrade it for Visual Studio 2010.  Start the application.  You’ll see something like the following:

AcmBrowser

This is a very handy tool, but unfortunately it takes a little time to get used to it.  The very first thing to do is enter your Service Namespace and Management Key (see A above).  You can get these off of the AppFabric portal (i.e. http://appfabric.azure.com) in the following places:

Service Namespace and Management Key

Note: Make sure to put a “-sb” at the end of your Service Namespace in the AcmBrowser tool.  This is because the tool calls the Access Control Management Endpoint, which by convention is your service namespace with a “-sb” appended to it.

Once you’ve entered these values, click the “Load from Cloud” button (see B above).  This will grab your existing settings and load them into the Resources list.  I recommend you click the “Save” button (see C above) to save a copy of them locally – this way you’ll have something to revert to if you make a mistake.

Okay, now that you have the basics loaded into AcmBrowser, here are the steps to setup Access Control:

  1. Right-click “Issuers” and click “Create”.  Enter the following values and press OK.
  2. Expand Scopes –> ServiceBus Scope for … –> Rules.
  3. Create a rule that will allow “joe” to Send messages to the Service Bus endpoint (remember “joe” from above?).  Right-click “Rules” and click “Create”.  Enter the following values and press OK.
  4. Create a rule that will allow “joe” to Send messages to the Service Bus endpoint (remember “joe” from above?).  Right-click “Rules” and click “Create”.  Enter the following values and press OK.
  5. Now you need to update Access Control.  Unfortunately, AcmBrowser doesn’t update Access Control, so you have to clear then save.
    • Click the “Clear Service Namespace in Cloud” button (see D above).
    • Click the “Save to Cloud” button (see E above).

That’s it for Access Control.  We’ve setup the SelfSTS as a trusted Issuer, and we’ve defined two rules – Send and Listen – for the claim “name” with a value of “joe”.

Modifying the EchoSample to Use

The rest of this sample is really pretty straightforward – we’ve either already done most of the work, or we’ll leverage a few code snippets from different resources.  The first thing we’ll do is add a GetSAMLToken method to the Service project in the EchoSample.  Add the following method in the Program.cs file:

Getting the SAML Token
  1. private static string GetSAMLToken(string identityProviderUrl, string identityProviderCertificateSubjectName, string username, string password, string appliesTo)
  2. {
  3.     GenericXmlSecurityToken token = null;
  4.  
  5.     var binding = new WS2007HttpBinding();
  6.  
  7.     binding.Security.Mode = SecurityMode.Message;
  8.     binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
  9.     binding.Security.Message.EstablishSecurityContext = false;
  10.     binding.Security.Message.NegotiateServiceCredential = true;
  11.  
  12.     using (var trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(new Uri(identityProviderUrl), new DnsEndpointIdentity(identityProviderCertificateSubjectName), new AddressHeaderCollection())))
  13.     {
  14.         trustChannelFactory.Credentials.UserName.UserName = username;
  15.         trustChannelFactory.Credentials.UserName.Password = password;
  16.         trustChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
  17.  
  18.         trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
  19.  
  20.         WSTrustChannel channel = null;
  21.  
  22.         try
  23.         {
  24.             var rst = new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue);
  25.             rst.AppliesTo = new EndpointAddress(appliesTo);
  26.             rst.KeyType = KeyTypes.Bearer;
  27.  
  28.             channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
  29.             token = channel.Issue(rst) as GenericXmlSecurityToken;
  30.             ((IChannel)channel).Close();
  31.             channel = null;
  32.  
  33.             trustChannelFactory.Close();
  34.  
  35.             string tokenString = token.TokenXml.OuterXml;
  36.             return tokenString;
  37.         }
  38.         finally
  39.         {
  40.             if (channel != null)
  41.             {
  42.                 ((IChannel)channel).Abort();
  43.             }
  44.  
  45.             if (trustChannelFactory != null)
  46.             {
  47.                 trustChannelFactory.Abort();
  48.             }
  49.         }
  50.     }
  51. }

This method is almost identical to the GetSAMLToken found in FabrikamShippingSaaS’s TestClient.  Here are the changes I made:

  • Line 1: I changed the return type from SecurityToken to string.  This is because the TransportClientEndpointBehavior will want the SAML token as a string.
  • Lines 5-10: I moved the code from the GetSecurityTokenServiceBinding method into the GetSamleToken method.  This is simply for readability in this blog post.
  • Line 32: I removed the following code: rst.Entropy = new Entropy(CreateEntropy());
  • Line 35: Added this line to grab the token out of the GenericXmlSecurityToken object.
  • Line 36: Returning the tokenString instead of the token.

    Now, there are a few values that we’re going to start in the App.config file.  Here they are:

    App.Config file
    1. <appSettings>
    2.   <add key="identityProviderCertificateSubjectName" value="adventureWorks" />
    3.   <add key="identityProviderUrl" value="http://localhost:8000/STS/Username" />
    4.   <add key="appliesTo" value="https://{0}-sb.accesscontrol.windows.net/WRAPv0.9" />
    5.   <add key="serviceNamespace" value="YOURSERVICENAMESPACE" />
    6.  
    7.   <!– this is the user and pwd of the user in AdventureWorks IdP –>
    8.   <add key="username" value="joe" />
    9.   <add key="password" value="p@ssw0rd" />
    10. </appSettings>

    Replace YOURSERVICENAMESPACE with your actual service namespace.

    Now, let’s create some static variables for these values in the Program.cs file:

    Static Variables
    1. static string identityProviderUrl = ConfigurationManager.AppSettings["identityProviderUrl"];
    2. static string identityProviderCertificateSubjectName = ConfigurationManager.AppSettings["identityProviderCertificateSubjectName"];
    3. static string username = ConfigurationManager.AppSettings["username"];
    4. static string password = ConfigurationManager.AppSettings["password"];
    5. static string serviceNamespace = ConfigurationManager.AppSettings["serviceNamespace"];
    6. static string appliesTo = String.Format(ConfigurationManager.AppSettings["appliesTo"], serviceNamespace);

    Now, we’re going to change a number of things within the Main method.  First, remove the Console.Write() and Console.ReadLine() sections – we’re grabbing those out of the App.Config file.  Next, we need to grab the SAML token.  Write the following line:

    Code Snippet
    1. string samlToken = GetSAMLToken(identityProviderUrl, identityProviderCertificateSubjectName, username, password, appliesTo);

    This will call the GetSAMLToken method and pass along all the values required in order to generate the SAML token.  When this runs, it will call out to SelfSTS and pass along the username/password specified in the App.Config file and, in return, get a SAML token that includes all the claims we want – including the “name”.

    Now, we have to take this SAML token as use it with the TransportClientEndpointBehavior.  Remove the existing TransportClientEndpointBehavior, and replace it with the following code:

    Code Snippet
    1. TransportClientEndpointBehavior samlCredentials = new TransportClientEndpointBehavior();
    2. samlCredentials.CredentialType = TransportClientCredentialType.Saml;
    3. samlCredentials.Credentials.Saml.SamlToken = samlToken;

    We’re now creating a new TransportClientEndpointBehavior with the CredentialType of TransportClientCredentialType.Saml, and setting the SamlToken property to our samlToken.  Mission accomplished!  (Note: since I changed the variable name to samlCredentials, but sure and update the code below where the TransportClientEndpointBehavior  is added as a behavior.)

    Feels good.  Now all we have to do is run it!

    Wrapping Up

    Alright, so now we’re ready to run it.  Grab the source code below.  When you run it, be sure and update YOURSERVICENAMESPACE (two instances) and YOURISSUERSECRET (one instance).  Also, be sure to start the projects in the following order:

    1. SelfSTS – we need to make sure our STS is running first.
    2. Service – when this starts it will grab the SAML token from SelfSTS, then connect to the Service Bus endpoint as a listener.
    3. Client – when this starts it will use the SharedSecret to connect to the Service Bus as a sender.

    When the Service starts and successfully connects as a listener, it should look like this:

    image

    After you startup the Client and echo some text, you’ll see the text reflected in the console window:

    image

    And that’s it!

    Now, the whole purpose of this is to highlight how to leverage the SAML token within the TransportClientEndpointBehavior class.  Obviously you’ll want to use something like ADFS 2.0 and not the SelfSTS in a production, but fortunately I can refer you to my disclaimer above and wish you good luck!

    Hope this helps!

    Special thanks to Vittorio Bertocci and Maciej ("Ski") Skierkowski for their help, and Scott Seely for asking the question that got me to pull this together.

    Not only is this my first time at TechEd EMEA, but it’s also my first time to Berlin.  While exhausting, it’s been a ton of fun!  I haven’t had a much time to explore the city yet, but I’ve spent a lot of time talking to customers about the Windows Azure Platform.

    Today I am delivering the presentation A Lap Around the Windows Azure AppFabric.

    Here’s the description:

    Come learn how to use services in the Windows Azure AppFabric (such as Service Bus, Access Control, and Caching) as building blocks for Web-based and Web-hosted applications, and how developers can leverage these services to create and extend applications in the cloud while also connecting them with on-premises systems.

    I’ll post links to the video and code downloads when they become available.

    Enjoy!

    Windows Azure AppFabric Today’s an exciting day!  During the keynote this morning at PDC10, Bob Muglia announced a wave of new building block services and capabilities for the Windows Azure AppFabric.  The purpose of the Windows Azure AppFabric is to provide a comprehensive cloud platform for developing, deploying and managing applications, extending the way you build Windows Azure applications today.   At PDC09, we announced both Windows Azure AppFabric and Windows Server AppFabric, highlighting a commitment to deliver a set of complimentary services both in the cloud and on-premises.  While this has long been an aspiration, we haven’t yet delivered on it – until today!

    Let me quickly enumerate the some of the new building block services and capabilities:

    • Caching (CTP at PDC) – an in-memory, distributed application cache to accelerate the performance of Windows Azure and SQL Azure-based applications.  This Caching service is the complement to Windows Server AppFabric Caching, and provides a symmetric development experience across the cloud and on-premises.
    • Service Bus Enhancements (CTP at PDC) – enhanced to add durable messaging support, load balancing for services, and an administration protocol.  Note: this is not a replacement of the live, commercial Service Bus offering, but instead a set of enhancements provided in the AppFabric LABS portal.
    • Integration (CTP in CY11) – common BizTalk Server integration capabilities (e.g. pipeline, transforms, adapters) as a service on Windows Azure.
    • Composite Application (CTP in CY11) – a multi-tenant, managed service which consumes the .NET based Composition Model definition and automates the deployment and management of the end-to-end   application.

    As part of the end-to-end environment for composite applications, there are a number of supporting elements:

    • AppFabric Composition Model and Tools (CTP in CY11) – a set of .NET Framework extensions for composing applications on the Windows Azure platform.  The Composition Model provides a way to describe the relationship between the services and modules used by your application.
    • AppFabric Container (CTP in CY11) – a multitenant, high density host optimized for services and mid-tier components.  During the keynote, James Conard showcased a standard, .NET WF4 running in the container.

    Want to get up to speed quickly?  Take a look at these resources for Windows Azure AppFabric:

    Watch these great sessions from PDC10 which cover various pieces of the Windows Azure AppFabric:

    Also, be sure to check out this interview with Karandeep Anand, Principal Group Program Manager with Application Platform Services, as he talks about the new Windows Azure AppFabric Caching service.

    Get Microsoft Silverlight

    Early next week my team, the Windows Azure Platform Evangelism team, will release a new version of the Windows Azure Platform Training Kit – in this kit we’ll have updated hands-on-labs for the Caching service and the Service Bus enhancements.   Be sure and take a look!

    Of course, I’ll have more to share over the new few days and weeks.

    WadeCloudCoverShow Ryan Dunn and Steve Marx have a great show on Channel9 called the Cloud Cover Show.  I’ve been watching it since the beginning, and have learned a lot about different features of the Windows Azure Platform, the latest news and announcements, as well as tips and tricks.  Naturally, I was honored (and a bit scared) when they asked me to join them on the show to talk about the Windows Azure AppFabric Service Bus.

    Let me state this for the record – I was right to be afraid! <grin>

    Let’s talk about how I was introduced – Wegner Clawed.  Watch it for yourself.  If you aren’t laughing hysterically then there’s something wrong with you.  And for the record I am not related to Joe Wegner (at least I hope not)!

    Wade's Funky Fresh Beat

    Next, Wade’s Funky Fresh Beat – a tribute to both Wegner Clawed and the funky beat in my post Using Social Web Providers in Less than 5 Minutes.  I’m moved that Steve took the time to put this together.

    Of course, we did manage to spend some time talking about the Service Bus, and even showed a few demos (with a funky beat, I might add).

    Get Microsoft Silverlight

    All-in-all, I had a ton of fun (despite losing a bit of dignity).  Can’t wait to come on again!