26 posts categorized "Service Bus / ISB"

09/18/2012

Federating Windows Azure Service Bus & Access Control Service with a custom STS: thinktecture IdentityServer helps with more real-world-ish Relay and Brokered Messaging

The Windows Azure Service Bus and the Access Control Service (ACS) are good friends – buddies, indeed.

Almost all official Windows Azure Service Bus-related demos use a shared secret approach to authenticate directly against ACS (although it actually is not an identity provider), get back a token and then send that token over to the Service Bus. This magic usually happens all under the covers when using the WCF bindings.

All in all, this is not really what we need and seek for in real projects.
We need the ability to have users or groups (or: identities with certain claims) authenticate against identity providers that are already in place. This IdP needs to be federated with the Access Control Service which then in turn spits out a token the Service Bus can understand.

Wouldn’t it be nice to authenticate via username/password (for real end users) or via certificates (for server/services entities)?

Let’s see how we can get this working by using our thinktecture IdentityServer. For the purpose of this blog post I am using our demo IdSrv instance at https://identity.thinktecture.com/idsrv.

The first thing to do is to register IdSrv as an identity provider for the respective Service Bus ACS namespace. Each SB namespace has a so called buddy namespace in ACS. The buddy namespace for christianweyer is christianweyer-sb. You can get to it by clicking the Access Control Service button in the Service Bus portal like here:

image

In the ACS portal for the SB buddy namespace we can then add a new identity provider.

image

image

thinktecture IdentityServer does support various endpoints and protocols, but for this scenario we are going to add IdSrv as a WS-Federation-compliant IdP to ACS. At the end we will be requesting SAML token from IdSrv.

image

The easiest way to add it to ACS is to use the service metadata from https://identity.thinktecture.com/idsrv/FederationMetadata/2007-06/FederationMetadata.xml

Note: Make sure that the checkbox is ticked for the ServiceBus relying party at the bottom of the page.

image

Next, we need to add new claims rules for the new IdP.

Let’s create a new rule group.

image

I am calling the new group IdSrv SB users. In that group I want to add at least one rule which says that a user called Bob is allowed to open endpoints on my Service Bus namespace.

image

In order to make our goal, we say that when an incoming claim of (standard) type name contains a value Bob then we are going to emit a new claim of type net.windows.servicebus.action with the Listen value. This is the claim the Service Bus can understand.
Simple and powerful.

image

We could now just add a couple more rules here for other users or even X.509 client certificates.

Before we can leave the ACS configuration alone we need to enable the newly created rule group on the ServiceBus relying party:

image

… and last but not least I have to add a new relying party configuration in Identity Server for my SB buddy namespace with its related WRAP endpoint:

image

Done.

For using the external IdP in my WCF-based Service Bus applications I wrote a very small and simpler helper class with extension methods for the TransportClientEndpointBehavior. It connects to the STS/IdP requesting a SAML token which is then used as the credential for the Service Bus.

 

using System;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Security;
using Microsoft.IdentityModel.Protocols.WSTrust;
using Microsoft.IdentityModel.Protocols.WSTrust.Bindings;
using Microsoft.ServiceBus;

namespace ServiceBus.Authentication
{
    public static class TransportClientEndpointBehaviorExtensions
    {
        public static string GetSamlTokenForUsername(
           this TransportClientEndpointBehavior behavior, string issuerUrl, string serviceNamespace, 
           string username, string password)
        {
            var trustChannelFactory =
                new WSTrustChannelFactory(
                    new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
                    new EndpointAddress(new Uri(issuerUrl)));

            trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
            trustChannelFactory.Credentials.UserName.UserName = username;
            trustChannelFactory.Credentials.UserName.Password = password;

            try
            {
                var tokenString = RequestToken(serviceNamespace, trustChannelFactory);
                trustChannelFactory.Close();

                return tokenString;
            }
            catch (Exception ex)
            {
                trustChannelFactory.Abort();
                throw;
            }             
        }       

        public static string GetSamlTokenForCertificate(
           this TransportClientEndpointBehavior behavior, string issuerUrl, string serviceNamespace, 
           string certificateThumbprint)
        {
            var trustChannelFactory =
                new WSTrustChannelFactory(
                    new CertificateWSTrustBinding(SecurityMode.TransportWithMessageCredential),
                    new EndpointAddress(new Uri(issuerUrl)));

            trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
            trustChannelFactory.Credentials.ClientCertificate.SetCertificate(
                StoreLocation.CurrentUser,
                StoreName.My,
                X509FindType.FindByThumbprint,
                certificateThumbprint);

            try
            {
                var tokenString = RequestToken(serviceNamespace, trustChannelFactory);
                trustChannelFactory.Close();            

                return tokenString;
            }
            catch (Exception ex)
            {
                trustChannelFactory.Abort();
                throw;
            }                
        }

        private static string RequestToken(string serviceNamespace, WSTrustChannelFactory trustChannelFactory)
        {
            var rst =
                new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue, 
                   WSTrust13Constants.KeyTypes.Bearer);
            rst.AppliesTo = new EndpointAddress(
                String.Format("https://{0}-sb.accesscontrol.windows.net/WRAPv0.9/", serviceNamespace));
            rst.TokenType = Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml2TokenProfile11;

            var channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
            var token = channel.Issue(rst) as GenericXmlSecurityToken;
            var tokenString = token.TokenXml.OuterXml;

            return tokenString;
        }
    }
}

 

Following is a sample usage of the above class.

static void Main(string[] args)
{
    var serviceNamespace = "christianweyer";
    var usernameIssuerUrl = 
       "https://identity.thinktecture.com/idsrv/issue/wstrust/mixed/username";

    var host = new ServiceHost(typeof(EchoService));

    var a = ServiceBusEnvironment.CreateServiceUri(
        "https", serviceNamespace, "echo");
    var b = new WebHttpRelayBinding();
    b.Security.RelayClientAuthenticationType =
        RelayClientAuthenticationType.None; // for demo only!
    var c = typeof(IEchoService);

    var authN = new TransportClientEndpointBehavior(); 
            
    var samlToken = authN.GetSamlTokenForUsername(
        usernameIssuerUrl, serviceNamespace, "bob", ".......");
                        
    authN.TokenProvider =
        TokenProvider.CreateSamlTokenProvider(samlToken);

    var ep = host.AddServiceEndpoint(c, b, a);
    ep.Behaviors.Add(authN);
    ep.Behaviors.Add(new WebHttpBehavior());

    host.Open();
    Console.WriteLine("Service running...");

    host.Description.Endpoints.ToList()
        .ForEach(enp => Console.WriteLine(enp.Address));

    Console.ReadLine();
    host.Close();
}

 

And the running service in action (super spectacular!)

image


Hope this helps!

04/27/2012

Measuring performance of your HTTP-based .NET applications: Performance Counters for HttpWebRequest

Just found this and thought to share it with you: Network Class Library Team (System.Net): New Performance Counters for HttpWebRequest

 

Each of the seven green circles represents one of the six performance counters (there are two ‘5’ items because 5 is the average lifetime, and there are two code paths that will affect that counter).

 

Note: Be aware that ‘new’ means new in .NET 4.0 (the blog post is from Aug 2009).

04/12/2012

You think WCF needs more of ‘you’? Go and vote for your most desired features now

The WCF team has set up a uservoice page for voting on WCF v-Next features. Go ahead and influence WCF!

04/02/2012

Slides for my sessions at DevWeek 2012

And here we go – as promised to all of you nice people attending one of my sessions last week in London.

 

If you have questions, please feel free to send my an email!

See you next year at DevWeek.

12/20/2011

Cross-device/cross-location Pub-Sub (part 3): Using Windows Azure Service Bus Topics & Subscriptions in Android with Mono for Android

And here we go with the final piece of blogging around the Windows Azure Service Bus and its cross-device, cross-location pub/sub features.

There have already been two articles about this topic (pun intended Winking smile)


Today I have built a very simple Android app with MonoDroid (aka Mono for Android) in C#. The code is essentially the same as for the iOS demo shown earlier (with MonoTouch), I just used Monodroid.Dialog to programmatically wire up the UI.

image

This is the entire code for the app:

   1:  [Activity(Label = "DroidServiceBusSubscriber",
   2:    MainLauncher = true, Icon = "@drawable/icon")]
   3:  public class MainActivity : Activity
   4:  {
   5:      private ListView lv;
   6:      private DialogAdapter da;
   7:      private RootElement menu;
   8:      private Section messages;
   9:      private BrokeredMessaging broker;
  10:      private string sbNamespace = "YOUR_SB_NS";
  11:      private string issuerName = "owner";
  12:      private string issuerSecret = "YOUR_OWNER_ISSUERKEY";
  13:      private string topicName = "newstopic";
  14:      private string subscriptionName = "androidsubscription";
  15:   
  16:      protected override void OnCreate(Bundle bundle)
  17:      {
  18:          base.OnCreate(bundle);
  19:   
  20:          InitBroker();
  21:          SetupUI();
  22:          RegisterMessagesHandler();
  23:      }
  24:   
  25:      private void InitBroker()
  26:      {
  27:          broker = new BrokeredMessaging(sbNamespace);
  28:          broker.GetToken(issuerName, issuerSecret);
  29:      }
  30:   
  31:      private void SetupUI()
  32:      {
  33:          messages = new Section("Messages");
  34:          menu = new RootElement("Service Bus Subscriber")
  35:          {
  36:              messages
  37:          };
  38:   
  39:          da = new DialogAdapter(this, menu);
  40:          lv = new ListView(this) { Adapter = da };
  41:              
  42:          SetContentView(lv);            
  43:      }
  44:   
  45:      private void RegisterMessagesHandler()
  46:      {
  47:          Task.Factory.StartNew(() =>
  48:          {
  49:              while (true)
  50:              {
  51:                  try
  52:                  {
  53:   
  54:                      var message = broker.ReceiveAndDeleteMessage(topicName + 
  55:                        "/Subscriptions/" + subscriptionName);
  56:   
  57:                      if (!String.IsNullOrWhiteSpace(message))
  58:                      {
  59:                          RunOnUiThread(delegate
  60:                          {
  61:                              messages.Elements.Add(new StringElement(message));
  62:                              da.NotifyDataSetChanged();
  63:                          });
  64:                      }
  65:   
  66:                  }
  67:                  catch (Exception ex)
  68:                  {
  69:                      Console.WriteLine(ex);
  70:                  }
  71:              }
  72:          });
  73:      }
  74:  }

 

And the ServiceBusBrokeredMessaging class is exactly copied and pasted from the MonoTouch project to the VS 2010 project for MonoDroid.

Here is the client app solution (you will need Mono for Android for Visual Studio):


Hope this helps.

12/15/2011

Cross-device/cross-location Pub-Sub (part 2): Using Windows Azure Service Bus Topics & Subscriptions in Windows Phone (7.1)

In the previous post I showed how to use MonoTouch and C# on iOS devices to subscribe to the Windows Azure Service Bus’s topics and subscriptions features.

This time it is a Windows Phone (Mango) client app.

The sending / publishing application is still the same Console application from the last post:

image

And the nice part about the WP app is that Kellabyte already did the major work for wrapping the Service Bus queues, topics, and subscriptions REST API (also check out her awesome Continuous Client demo which uses the Service Bus). Smile

With her code in place the actual subscribing inside my WP app to the messages in my Service Bus subscriptions is a piece of cake:

   1:  public MainPage()
   2:  {
   3:      InitializeComponent();
   4:   
   5:      InitBroker();
   6:  }
   7:   
   8:  private void InitBroker()
   9:  {
  10:      token = new Token(sbNamespace, issuerName, issuerSecret);
  11:      token.Requested += new EventHandler<TokenEventArgs>(token_Requested);
  12:      token.Request();
  13:  }
  14:   
  15:  private void token_Requested(object sender, TokenEventArgs e)
  16:  {
  17:      topic = new Topic(token, topicName);
  18:   
  19:      RegisterMessagesHandler();
  20:  }
  21:   
  22:  private void RegisterMessagesHandler()
  23:  {
  24:      subscription = new Subscription(topic, subscriptionName);
  25:      subscription.MessageRecieved += 
  26:                    new EventHandler<SubscriptionMessageEventArgs>(
  27:                      subscription_MessageRecieved);
  28:      subscription.ReceiveMessage();
  29:  }
  30:   
  31:  private void subscription_MessageRecieved(object sender, SubscriptionMessageEventArgs e)
  32:  {
  33:      var message = e.Message;
  34:   
  35:      try
  36:      {
  37:          if (!String.IsNullOrWhiteSpace(message))
  38:          {
  39:              Dispatcher.BeginInvoke(() =>
  40:              {
  41:                  mainContentPanel.RowDefinitions.Add(
  42:                      new RowDefinition { Height = new GridLength(35) });
  43:   
  44:                  var pos = mainContentPanel.RowDefinitions.Count - 1;
  45:   
  46:                  var txt = new TextBlock();
  47:                  txt.Text = message;
  48:                  mainContentPanel.Children.Add(txt);
  49:                  Grid.SetColumn(txt, 0);
  50:                  Grid.SetRow(txt, pos);
  51:              });
  52:          }
  53:      }
  54:      catch (Exception ex)
  55:      {
  56:          Console.WriteLine(ex);
  57:      }
  58:   
  59:      subscription.ReceiveMessage();
  60:  }


And the (again) super spectacular result is that all the messages are being sucked from my subscription and displayed on the phone:

image

Voila. Sorry – not so exciting as last time. Anyway, here is the download:


Hope this helps.

12/14/2011

Cross-device/cross-location Pub-Sub: Using Windows Azure Service Bus Topics & Subscriptions in iOS with MonoTouch

Windows Azure has seen some updates over the past weekend. One small update is that the Service Bus and Access Control Service are no longer marketed inside the Windows Azure AppFabric brand but are now a substantial part of Windows Azure core.

The Windows Azure Service Bus has two basic feature sets:

  • relayed messaging (through the Service Bus Relay service)
  • brokered messaging (through queues, topics, subscriptions (and the deprecated message buffers)

In this post I show you how to use part of Service Bus’ REST API to create a cross-platform & cross-location publish & subscribe app by leveraging topics and subscriptions.

First of all, let’s launch the wonderful Service Bus Explorer tool and look at my Service Bus namespace:

image

As we can see there are no topics and subscriptions (and also no queues).

What we are going to do is have a .NET console app running on Windows to create a topic and a subscription on the Service bus with the REST API and send messages to the topic. Here is the essential piece of code to do this:

   1:  var broker = new BrokeredMessaging (serviceNamespace);
   2:              
   3:  try
   4:  {
   5:      token = broker.GetToken (issuerName, issuerSecret);
   6:                  
   7:      string topicName = "newstopic";
   8:      string subscriptionName = "iphonesubscription";
   9:   
  10:      broker.CreateTopic(topicName);
  11:      broker.CreateSubscription(topicName, subscriptionName);
  12:                  
  13:      while (true)
  14:      {
  15:          broker.SendMessage (topicName, "Hello " + Guid.NewGuid ().ToString ());
  16:          Thread.Sleep (5000);                    
  17:      }
  18:  }
  19:  catch (WebException we)
  20:  ...


Admitted, the actual heavy work is inside the BrokeredMessaging class. This class is just a simple wrapper around the REST API, and you can see some basic operations using WebClient to talk to the Service Bus in the AppFabric SDK samples (e.g. the Management Operations using REST sample).

The BrokeredMessaging helper class can be found in the sample projects download at the end of this post.

After we retrieved a token from ACS we create a topics and a subscription and send out messages in a loop:

image

These messages are sent to the Service Bus to a durable topic (which uses queues underneath). As long as there is no subscriber which gets and deletes the messages from the subscription we can see the messages sent to the topic in the Service Bus Explorer – here we have sent out 4 messages from the Console application:

image

Cool.

Now let’s use a subscriber to get the messages from the subscription. My goal was to have a native iOS app but built with C# entirely. Therefore I fired up MonoTouch and created a very simple iPhone app. For the super-sophisticated UI I used MonoTouch.Dialog, a highly recommend UI library to quickly create any forms-over-data user interface for iOS apps.

In order to talk to the Service Bus the MonoTouch project was using the exact same BrokeredMessaging class as my Windows console application. The joy of MonoTouch.

Again, the essential code (after getting a token from ACS) to get and delete messages from the SB subscription looks like this (the messages object is the list of elements in the UI to display the messages).

private void RegisterMessagesHandler ()
{
    Task.Factory.StartNew (() =>
    {
        while (true)
        {
            try
            {
                    
                var message = broker.ReceiveAndDeleteMessage (topicName + 
                   "/Subscriptions/" + subscriptionName);
                    
                if (!String.IsNullOrWhiteSpace (message))
                {
                    InvokeOnMainThread (delegate 
                    { 
                        messages.Elements.Add (new StringElement (message));
                        dvc.TableView.ReloadData ();
                    });
                } 
                    
            }
            catch (Exception ex)
            {
                Console.WriteLine (ex);                
            }
        }
    });
}


Note: it may not be wise to store the Service Bus owner and shared secret directly in the device’s app – you know… or at least store it in the Keychain (sample with MT: http://www.wildsau.net/post/2011/02/01/iOS-Store-passwords-in-the-keychain-using-MonoTouch.aspx).

To convince you that there is no magic or cheating going on, this is the code from BrokeredMessaging  to get the message from the subscription (and also delete it):

   1:  public string ReceiveAndDeleteMessage (string relativeAddress)
   2:  {
   3:      string fullAddress = baseAddress + relativeAddress + 
   4:        "/messages/head" + "?timeout=60";
   5:              
   6:      Console.WriteLine ("\nRetrieving message from {0}", fullAddress);
   7:              
   8:      var webClient = new WebClient ();
   9:      webClient.Headers [HttpRequestHeader.Authorization] = token;
  10:   
  11:      var response = webClient.UploadData (fullAddress, 
  12:        "DELETE", new byte[0]);
  13:      var responseStr = Encoding.UTF8.GetString (response);
  14:   
  15:      Console.WriteLine (responseStr);
  16:              
  17:      return responseStr;
  18:  }

Note: Console.WriteLine(…) is the mechanism in MonoTouch to write to debug output. Well…

Whenever we get a real and non-empty message we add it to the list view of our simple iOS app. Voila:

image

And to prove that everything worked as expected, the subscription is now empty and no more messages are in there:

image

Bingo! Smile

Windows Azure Service Bus (together with the Windows Azure Access Control Service) enables us to send messages in an async manner to durable storage in the Cloud and subscribing to those messages (via topics and subscriptions) with literally any device, any platform, from any location!


The sample projects for VS 2010 and MonoTouch can be downloaded:


Hope this helps.

10/21/2011

Materials for my sessions at Software Architect 2011

As promised in and after the sessions at the wonderful Software Architect 2011 conference in London:

  • Designing & building services the web & HTTP way with WCF 4.5 (Slides  |  Samples [this is the CodePlex Preview 5 branch with samples)
  • Windows Azure platform for Architects (Slides)

Thank you to everybody attending and giving such nice feedback. Hope to see you next time around.

10/03/2011

Unterlagen & Demos zu meinen Sessions & Workshop auf der BASTA! 2011

So – die BASTA! ist vorbei und wir von thinktecture hatten mal wieder eine super Zeit in Mainz. Danke an das Team von S&S Media und vor allem an die Teilnehmer!

Hier finden Sie die Folien und Beispiele zu meinen Sessions und dem Workshop auf der Herbst-BASTA! 2011:

  • Nicht nur Web: Android und iOS Apps mit HTML5 und Co. (Slides | Samples)
  • Kommunikation über die Cloud: Windows Azure AppFabric Service Bus (Slides | Samples)
  • Offen für's "Web": Web APIs mit WCF in .NET 4.0+ (Slides | Samples [this is the Preview 5 branch with samples])
  • Hands-On Windows Azure Platform: Ihr Tag in der Cloud [mit Dominick Baier] (Samples)

 

Wenn Fragen sind wie immer eine EMail an mich (schauen Sie einfach in den Slides nach…). Danke.

Bis bald!

01/10/2011

thinktecture StarterSTS now officially ‘powered by Windows Azure’

A few hours ago I got the final notice that StarterSTS is now officially allowed admittance to the Azure Cloud olymp:

 

OK, Dominick: up to releasing 1.5… Smile