November 2011 - Posts
I wanted to demonstrate how Windows Server AppFabric Monitoring works for WCF services, but when I called my services I did not see any recording of any WCF call. Why?
It took me some time to find the problem. To make the story short. AppFabric monitoring relies on SQL Agent.
WCF event are written to a database that is set when we configure AppFabric Hosting Service.


This information is written to the "ApplicationServerMonitoringConnectionString" connection string in the root web.config of the server
When the system is working properly, WCF events are written to the ASStagingTable table in the monitoring database and then move into the ASWcfEvents view. For SQL Express, this will happen using the SQL Broker. For other SQL Server products, the SQL Agent is responsible for moving the events. So if you want AppFabric monitoring to work the broker must enabled for SqlExpress and the SQL Agent must be running for other SQL servers.
A found I great document for troubleshooting Windows Server AppFabric here.
Hope this helps
Manu
Windows Azure SDK 1.6 was released a couple of days ago - it's the November release. It includes updates to the Windows Azure Tools for Visual Studio 2010 and Windows Azure Libraries for .NET, in addition to other fixes and performance improvements.
The entire Windows Azure SDK 1.6 is available for download. The Windows Azure Tools for Visual Studio 2010 can be obtained separately via the Web Platform Installer.
The objective with this update to the tools for Visual Studio 2010 is to make it possible for developers to manage all aspects of application creation and deployment from within Visual Studio, rather than having to create services, manage configuration and multiple environments from the Azure developer portal. Some features this release include:
- Improved In-Place Updates
- Multiple profile support (publish settings, cloud configuration and build configuration will all be stored in MSBuild files)
- Ability to create hosted services and Azure storage accounts from within Visual Studio
- Publishing improvements (developers can use a publish settings file rather than having to connect to the Windows Azure portal)
- More verbose Activity Logs
- Streamlined Remote Desktop connectivity (no need to upload a certificate)
- Ability to use multiple Windows Azure Subscriptions
- Team Build supports command-line application packaging
In addition to the Visual Studio Tools, the SDK includes updates to the Windows Azure Compute and Storage Emulators and the Windows Azure Libraries for .NET 1.6. Service Bus and caching client libraries have been updated and no longer require separate installation (this was previously known as the Windows Azure AppFabric SDK).
The November release also adds modules for working with the new Windows Azure HPC Scheduler SDK.
Manu
I was working with a customer that wanted to use AppFabric Topics to push notifications to clients. as We all know anyone who wants to listen or send messages using service bus has to authenticate first. Traditionally authentication to the service bus was done by presenting a secret key before a connection was established.It is reasonable to put the secret key in a software package deployed on a server (Some can argue with that and say it is a security violation) but providing the key to numerous clients? This is a true security breach.
So How can we make clients listen on the service bus without having to provide them with our secret key?
Access Control Service is the solution.
The new version of Service bus which was released few weeks ago uses ACS to federate its authentication. We can use ACS to create new identities or federate with other identity providers so the actual user can use its own credentials to get a token that can be used against service bus. We can assign different permissions to the service bus users. It is possible to give listen, send, and manage permissions so we can make sure that users can execute only the actions we allow them to.
How do we set this?
Well for each service bus namespace (such as "manublog") a twin namespace (e.g. "manublog-sb") is created in ACS.
Let us open the management portal for service bus and select out namespace. By pressing on the Access Control Service button the portal of ACS for the twin namespace will be opened.


here we can register other identity providers that we want to federate with (such as a custom STS or ADFS 2.0)
In the relying party section we register the uri of the service bus resource we want to expose to our user. For example a queue a topic or a relay service (e.g. http://manublog.servicebus.windows.net/mytopic/subscriptions/manu)
In the rule group section we add rules that will be used to create a claim of type "net.windows.servicebus.action" with the value "Listen or Send or Manage".
In the portal we will find a definition of a relying party referencing the root of our service bus namespace. we can reference that as an example for defining new relying parties.

In the namespace there are existing rules for the super user "owner" that have full access to the entire namespace. we can reference these rules as examples for creating new ones.

In the portal we will find the definition of the super user "owner"
We can reference this as an example for our new identities definition.

Clemens Vasters recorded a great video describing all these capabilities in details. I strongly recommend to watch it.
To summarize
ACS is now integrated with AppFabric Service bus. This allows us to have full control who will use our communication channels implemented in service bus without exposing our secrets.
Enjoy
Manu
Recently the AppFabric team released real pub-sub capabilities with the new queues and topics features.
Queues are simple. AppFabric provides a queue for durable messaging between senders and receivers. Topics are interesting because they allows to create different subscriptions so different clients can receive only the messages they need.
To demonstrate how to use topics I created two helper classes: Senders and Receiver that will send and receive messages using AppFabric Topics.
Sender
- /// <summary>
- /// Send messages to AppFabric Topic
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public class ServiceBusSender<T> : IBrokeredMessageSender<T>
- {
- private string m_ServiceNamespace;
- private string m_IssuerName;
- private string m_IssuerKey;
- private Uri m_serviceUri;
- private TokenProvider m_tokenProvider;
- private TopicDescription m_topicDescriptor;
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="topicName">The name of the topic to use</param>
- public ServiceBusSender(string topicName)
- {
- m_ServiceNamespace = ServiceBusConfigurationAccessor.AppFabricServiceNamespace;
- m_IssuerName = ServiceBusConfigurationAccessor.AppFabricIssuerName;
- m_IssuerKey = ServiceBusConfigurationAccessor.AppFabricIssuerKey;
-
- m_tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(m_IssuerName, m_IssuerKey);
- m_serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", m_ServiceNamespace, string.Empty);
- NamespaceManager namespaceManager = new NamespaceManager(m_serviceUri, m_tokenProvider);
-
- if (!namespaceManager.TopicExists(topicName))
- m_topicDescriptor = namespaceManager.CreateTopic(topicName);
- else
- m_topicDescriptor = namespaceManager.GetTopic(topicName);
-
- }
-
- /// <summary>
- /// Send a message to the topic
- /// </summary>
- /// <param name="messageContent"></param>
- public void SendMessage(T messageContent)
- {
- Contract.Requires(messageContent != null);
-
- MessagingFactory factory = MessagingFactory.Create(m_serviceUri, m_tokenProvider);
- TopicClient myTopicClient = factory.CreateTopicClient(m_topicDescriptor.Path);
- BrokeredMessage message = new BrokeredMessage(messageContent);
-
- //All the message's properties are propagated so they can be used in a Sql Filter
- foreach (var prop in typeof(T).GetProperties())
- {
- message.Properties.Add(prop.Name, prop.GetValue(messageContent, null));
- }
-
- myTopicClient.Send(message);
- myTopicClient.Close();
- }
-
- }
As you can see the sender creates the topic (if it does not exist already). A messaging factory to create a client that can send messages to the topic. For that we need to supply the credentials for our namespace when we create the factory. To send a message to the topic we have to wrap our data in a BrokeredMessage. One of the capabilities we gain when doing that is properties propagation. A propagated property can participate a sql-like rule for filtering messages (will be defined by the client's subscription). In this sender we propagate all the properties. In real life you might choose to propagate only a the properties that participate in filtering because propagation costs.
Receiver
- /// <summary>
- /// Listen on an AppFabric service bus topic. One receiver can listen on multiple subscriptions
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public class ServiceBusReceiver<T> : IBrokeredMessageReceiver<T>
- {
- private string m_ServiceNamespace;
- private string m_IssuerName;
- private string m_IssuerKey;
- private Dictionary<string, SubscriptionClient> m_subscriptions;
- private MessagingFactory m_factory;
- private Uri m_serviceUri;
- private TokenProvider m_tokenProvider;
-
- /// <summary>
- /// The name of the topic to use
- /// </summary>
- public string TopicName { get; set; }
-
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="topicName">The name of the topic to listen to</param>
- public ServiceBusReceiver(string topicName)
- {
- m_subscriptions = new Dictionary<string, SubscriptionClient>();
- m_ServiceNamespace = ServiceBusConfigurationAccessor.AppFabricServiceNamespace;
- m_IssuerName = ServiceBusConfigurationAccessor.AppFabricIssuerName;
- m_IssuerKey = ServiceBusConfigurationAccessor.AppFabricIssuerKey;
- m_tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(m_IssuerName, m_IssuerKey);
- m_serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", m_ServiceNamespace, string.Empty);
- m_factory = MessagingFactory.Create(m_serviceUri, m_tokenProvider);
- TopicName = topicName;
- }
-
- /// <summary>
- /// Create a new subscription
- /// </summary>
- /// <param name="subscriptionName">The name of the subscription to create</param>
- /// <param name="filter">filter to use for filtering messages</param>
- public void InitSubscription(string subscriptionName, Filter filter=null)
- {
- Contract.Requires(!string.IsNullOrEmpty(subscriptionName));
- Contract.Requires(!string.IsNullOrEmpty(TopicName), "Topic name must be provided. Use the receiver's TopicName property");
-
- var namespaceManager = new NamespaceManager(m_serviceUri, m_tokenProvider);
-
- if (!namespaceManager.TopicExists(TopicName))
- namespaceManager.CreateTopic(TopicName);
-
- if (!namespaceManager.SubscriptionExists(TopicName, subscriptionName))
- {
- filter = (filter == null) ? new TrueFilter() : filter;
- namespaceManager.CreateSubscription(TopicName, subscriptionName, filter);
- }
-
- if (!m_subscriptions.ContainsKey(subscriptionName))
- m_subscriptions.Add(subscriptionName, m_factory.CreateSubscriptionClient(TopicName, subscriptionName, ReceiveMode.ReceiveAndDelete));
- }
-
- /// <summary>
- /// Delete a new subscription from the topic
- /// </summary>
- /// <param name="subscriptionName">The name of the subscription to delete</param>
- public void DeleteSubscription(string subscriptionName)
- {
- Contract.Requires(!string.IsNullOrEmpty(subscriptionName));
- Contract.Requires(!string.IsNullOrEmpty(TopicName), "Topic name must be provided. Use the receiver's TopicName property");
-
-
- var namespaceManager = new NamespaceManager(m_serviceUri, m_tokenProvider);
- if (namespaceManager.TopicExists(TopicName) && namespaceManager.SubscriptionExists(TopicName, subscriptionName))
- namespaceManager.DeleteSubscription(TopicName, subscriptionName);
- }
-
-
- /// <summary>
- /// Start listening on a subscription
- /// </summary>
- /// <param name="subscriptionName">The name of the subscription to listen to</param>
- /// <param name="processMessage">A function to trigger for each comming message</param>
- public void ReceiveMessages(string subscriptionName, Action<T> processMessage)
- {
- Contract.Requires(!string.IsNullOrEmpty(subscriptionName));
- Contract.Requires(m_subscriptions.ContainsKey(subscriptionName));
-
- try
- {
- Task.Factory.StartNew(() =>
- {
- while (m_subscriptions.ContainsKey(subscriptionName))
- {
- BrokeredMessage message;
- while ((message = m_subscriptions[subscriptionName].Receive(TimeSpan.FromSeconds(5))) != null)
- {
- processMessage(message.GetBody<T>());
- }
- }
- });
- }
- catch (Exception ex)
- {
- // Log this
- throw;
- }
-
- }
-
-
- /// <summary>
- /// Stop Listening on a subscription and delete it from the current subscriptions list
- /// </summary>
- /// <param name="subscriptionName">The name of the subscription</param>
- public void StopReceiveNessages(string subscriptionName)
- {
- if (!m_subscriptions.ContainsKey(subscriptionName))
- return;
-
- var subscriptionClient = m_subscriptions[subscriptionName];
-
- if ((subscriptionClient != null) && (!subscriptionClient.IsClosed))
- subscriptionClient.Close();
-
- subscriptionClient = null;
- m_subscriptions.Remove(subscriptionName);
- }
-
-
- }
The receiver can handle a collection of subscriptions. (Use InitSubscription to create one).
After a subscription is created call ReceiveMessages and provide a method to run for each message received. The receiver will constantly pool the topic and wait for a message as long as the subscription exist. When a message arrives it will extract the data object out of the brokered message at trigger the method you provided on the data.
The following test demonstrate how to use the sender and receiver.
Code Snippet
- [TestMethod]
- public void ServiceBusSenderAndReceiverTest()
- {
- var sender = new ServiceBusSender<TestMessage>("testTopic");
- var receiver = new ServiceBusReceiver<TestMessage>("testTopic");
- var finished = new AutoResetEvent(false);
-
- receiver.InitSubscription("testSubscription");
- receiver.ReceiveMessages("testSubscription",
- (msg) => { Assert.AreEqual(39, msg.Age); Assert.AreEqual("manu", msg.Name); finished.Set(); });
- sender.SendMessage(new TestMessage() { Name = "manu", Age = 39 });
-
- finished.WaitOne();
- receiver.DeleteSubscription("testSubscription");
- }
Enjoy
Manu
Security Token Services (STS) expose metadata in a special metadata files. Usually the file is exposed to the web in the address baseStsAddress/FederationMetadata/2007-06/FederationMetadata.xml so typical customers can download the file and fetch the information required to use the STS.
The metadata file contain information about the endpoints exposed, the claims the STS can produce, the signing key and algorithms.
Producing the metadata file is not trivial this is why we do not want to do this manually each time something changes in our custom STS. So instead of creating a real (static) metadata file we will create a mechanism that will produce the metadata file automatically each time someone will request it.
The best approach to do that is simply to create a custom Http handler that will do the job.
So lets do it…
Code Snippet
- /// <summary>
- /// Handler to dynamicaly create the federation metadata document
- /// </summary>
- public class FederationMetadataHandler : IHttpHandler
- {
- public void ProcessRequest(HttpContext context)
- {
- context.Response.ClearHeaders();
- context.Response.Clear();
- context.Response.ContentType = "text/xml";
- CustomSecurityTokenServiceConfiguration.Current.SerializeMetadata(context.Response.OutputStream);
- }
- public bool IsReusable { get { return false; } }
- }
Inside the CustomSecurityTokenConfiguration (see how to create a custom STS) let us add the following methods.
Code Snippet
- /// <summary>
- /// Create the metadata document for this STS
- /// </summary>
- /// <param name="stream"></param>
- public void SerializeMetadata(Stream stream)
- {
- var context = HttpContext.Current;
- var baseUri = new Uri(new Uri(context.Request.Url.AbsoluteUri), context.Request.ApplicationPath);
-
- if (entity == null)
- entity = GenerateEntities(baseUri.AbsoluteUri);
-
- context.Response.ContentEncoding = Encoding.UTF8;
- context.Response.ContentType = "text/xml";
- context.Response.ContentEncoding = Encoding.UTF8;
- var ser = new MetadataSerializer();
- ser.WriteMetadata(context.Response.OutputStream, entity);
- }
-
- private EntityDescriptor GenerateEntities(string baseUri)
- {
-
- SecurityTokenServiceDescriptor sts = GetTokenServiceDescriptor(baseUri);
- FillOfferedClaimTypes(sts.ClaimTypesOffered);
- FillSupportedProtocols(sts);
-
- var entity = new EntityDescriptor(new EntityId(string.Format("{0}/activeSTS.svc", baseUri))) { SigningCredentials = this.SigningCredentials };
- entity.RoleDescriptors.Add(sts);
- return entity;
- }
-
-
- private SecurityTokenServiceDescriptor GetTokenServiceDescriptor(string baseUri)
- {
- var tokenService = new SecurityTokenServiceDescriptor();
- tokenService.ServiceDescription = "NiceSTS";
-
- KeyDescriptor signingKey = new KeyDescriptor(this.SigningCredentials.SigningKeyIdentifier) { Use = KeyType.Signing };
- tokenService.Keys.Add(signingKey);
-
- EndpointAddress activeEndpoint = new EndpointAddress(string.Format("{0}/activeSTS.svc", baseUri));
- tokenService.SecurityTokenServiceEndpoints.Add(activeEndpoint);
- tokenService.TargetScopes.Add(activeEndpoint);
-
- return tokenService;
- }
-
-
- private void FillSigningKey(SecurityTokenServiceDescriptor sts)
- {
- KeyDescriptor signingKey = new KeyDescriptor(this.SigningCredentials.SigningKeyIdentifier) { Use = KeyType.Signing };
- sts.Keys.Add(signingKey);
- }
-
- private void FillSupportedProtocols(SecurityTokenServiceDescriptor sts)
- {
- sts.ProtocolsSupported.Add(new System.Uri(WSFederationConstants.Namespace));
- }
-
-
- private void FillOfferedClaimTypes(ICollection<DisplayClaim> claimTypes)
- {
- claimTypes.Add(new DisplayClaim(WSIdentityConstants.ClaimTypes.Name, "Name", ""));
- claimTypes.Add(new DisplayClaim(NICE.CustomSTS.ClaimTypes.TenantId, "TenantId", ""));
- claimTypes.Add(new DisplayClaim(Microsoft.IdentityModel.Claims.ClaimTypes.Role, "Role", ""));
- }
Now we need to attach the custom handler and we are done.
<location path="FederationMetadata/2007-06">
<system.webServer>
<handlers>
<add name="MetadataGenerator" path="FederationMetadata.xml"
verb="GET" type="MyCustomSTS.FederationMetadataHandler" />
</handlers>
</system.webServer>
<system.web>
<!--<customErrors mode="Off"/>-->
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Hope this helps
Manu
SSL is required for a growing number of scenarios yet a public certificate which is produced by a trusted certificate authority is not always available. In such scenarios we use self signed certificates. The problems with these certificates is that all certificate validation mechanisms will fail. To overcome that we need to do the following:
1. Disable WCF certificate validation
<endpointBehaviors>
<behavior name="clientBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
2. Disable Http certificate validation
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(delegate { return true; });
3. Make sure that the domain name (of the site or service we call) and the certificate name that power the SSL channel must match.
Hope this helps
Manu
In Claim based applications we use token to provide the application (Relying party) with details (a collection of claims) about the the authenticated identity.
In ASP.net web sites and WCF SOAP services SAML tokens are used as a container for the claims. SAML is a standard that describe how token and claims are constructed and how they are cryptographically protected using digital signature and encryption. SAML tokens are powerful yet they are large. The size of the token is not a real issue in ASP.Net web sites as well as in SOAP WCF services but for REST web services it is a problem.
The solution is a simpler and shorter token called SWT token (Simple Web Token). SWT is a simple header we attach to the http request sent to our REST service. The header contains a set of key value pairs. Of course SWT have a format we need to follow. It is protected with SHA256 HMACs and follow the spec that can be found here.
Constructing the token is not complicated but it is tedious. AppFabric Access Control Service can help here. It can transform SAML tokens to SWT tokens or create brand new SWT tokens for users it manages. (see the following sample)
To transform SAML tokens to SWT tokens we first need to get a SAML token. To do that we need to build a custom STS or a use ADFS 2.0. (In future posts I will not describe how to build a custom STS.)
Now we need to go to the ACS portal and create a configuration for our application.
we have to create a namespace for access control service if we haven't done that previously and then press "access control service"

Now we define an Identity provider (our custom STS that produce SAML tokens), a relying party (our application) for which we define that we want to generate SWT tokens,

and finally we define rule groups that defines how to construct the SWT token based on the information provided by the SAML token provided.
Now our application needs to call the custom STS and retrieve the SAML Token.
/// <summary>
/// Call an STS and get a SAML Token
/// </summary>
// <param name="stsAddress">The name of the sts that generates the SAML token</param>
/// <param name="acsStsAddress">The ACS endpoint that will accept the SAML token that will be generated</param>
/// <param name="username">username with which the client authenticate to the STS</param>
/// <param name="password">password with which the client authenticate to the STS</param>
/// <returns></returns>
public static string GetSamlAssertion(string stsAddress, string acsStsAddress, string username, string password)
{
var trustChannelFactory = new WSTrustChannelFactory("CustomSTSEP");
trustChannelFactory.Credentials.UserName.UserName = username;
trustChannelFactory.Credentials.UserName.Password = password;
RequestSecurityToken rst = new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue,
WSTrust13Constants.KeyTypes.Bearer);
rst.AppliesTo = new EndpointAddress(acsStsAddress);
rst.TokenType = Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml2TokenProfile11;
WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
GenericXmlSecurityToken token = channel.Issue(rst) as GenericXmlSecurityToken;
return token.TokenXml.OuterXml;
}//this is the configuration I used:
<client>
<endpoint name = "CustomSTSEP"
address="https://localhost/MySTS/activeSTS.svc/username_over_transport"
binding="ws2007HttpBinding"
bindingConfiguration="IdentityProviderBindingConfiguration"
contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustChannelContract">
</endpoint>
</client>
<bindings>
<ws2007HttpBinding>
<binding name="IdentityProviderBindingConfiguration">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="clientBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Once we hold the SAML Token we can send it to the ACS and get the SWT token we need.
/// <summary>
/// Get a SWT Token from Appfabric ACS using a SAML token that was previously generated
/// </summary>
/// <param name="scope">The realm of the application (RP) to which the token is generated</param>
/// <param name="samlAssertion">The SAML token that will be transformed to SWT token</param>
/// <returns></returns>
public static string GetSwtTokenFromACS(string scope, string samlAssertion)
{
// request a token from ACS WebClient client = new WebClient(); client.BaseAddress =
string.Format("https://{0}.{1}", ACSNamespace, "accesscontrol.windows.net"); var values = new NameValueCollection { { "wrap_assertion_format", "SAML"}, { "wrap_assertion", samlAssertion }, { "wrap_scope", scope } }; byte[] responseBytes = null; try { responseBytes = client.UploadValues("WRAPv0.9/", "POST", values); } catch (WebException ex) { var reader = new StreamReader(ex.Response.GetResponseStream()); Logger.Instance.WriteCritical(ex, reader.ReadToEnd()); } string response = Encoding.UTF8.GetString(responseBytes); return HttpUtility.UrlDecode( response .Split('&') .Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase)) .Split('=')[1]);
}
Now we can call our REST service…
WebClient client = new WebClient(); string headerValue = string.Format("WRAP access_token=\"{0}\"", swttoken); client.Headers.Add("Authorization", headerValue); Stream stream = client.OpenRead(address);
Enjoy
Manu