Windows AppFabric (Previously known as Dublin) introduces a new built-in mechanism for monitoring the execution of the WCF services, all the events generated during the execution or the interaction with other services. While the message trace capabilities in WCF already provided some detail about the execution and the exchanged messages, it was a feature more suitable for troubleshooting and error diagnosis. The performance counters did not help in this area either, as they provided live service usage statistics, which sometimes resulted very useful to determine possible bottlenecks.
When this monitoring mechanism is enabled for IIS Hosted services, the AppFabric extension will capture different events during the execution of the services. The level of detail or number of events that you want to capture is something that can be adjusted through configuration.
In order to configure monitoring for an existing WCF service, you need to add the following section to the web.config file,
<microsoft.applicationServer>
<monitoring>
<default enabled="true" connectionStringName="DefaultApplicationServerExtensions" monitoringLevel="Troubleshooting" />
</monitoring>
</microsoft.applicationServer>
The connectionStringName attribute should contain a reference to an existing connection string in the ConnectionString section, and that’s the database used by AppFabric to store the monitoring events.
The monitoringLevel attribute specifies the number of events you want to capture in a service execution. The possible values for this setting are,
- Off (monitoringLevel="Off”): No data is collected. It would be equivalent to have monitoring disabled.
- Errors only (monitoringLevel="ErrorsOnly”): Only errors and warnings events are collected. This is very useful when you don’t want to incur into performance issues for collecting application events but you still want to know about any error may happen during the execution.
- Health Monitoring (monitoringLevel=HealthMonitoring): This is the default level and collects enough application events to show different metrics in the AppFabric dashboard.
- End To End Monitoring (monitoringLevel="EndToEndMonitoring”). It collects all the events from the Health Monitoring level, plus additional events to reconstruct the message flow. For example, Service A called Service B. You will get also events representing info about the Service B call if monitoring is enabled on Service A.
- Troubleshooting (monitoringLevel="Troubleshooting"). This is the most verbose of all, so it is appropriate for troubleshooting an unhealthy application.
All this monitoring infrastructure is layered on top of “Event Tracing for Windows (ETW)”, which provides a very efficient and optimized mechanism for capturing application events without affecting the application performance at all. In addition, this infrastructure is complemented with a windows service for collecting the events (A ETW listener basically), and providers for dumping all the information to different storages. This last part is totally extensible, and you can configure your own implementation by implementing the interface Microsoft.ApplicationServer.Monitoring.EventCollector.IBulkCopy in the Monitoring.ApplicationServer.Monitoring assembly. This interface looks quite simple to implement, and AppFabric ships with a default implementation for SQL Server.
public interface IBulkCopy
{
int BatchSize { get; set; }
DbConnection Connection { get; set; }
string DestinationTableName { get; set; }
void WriteToServer(DataTable dataTable);
}
The windows service for collecting the ETW events can be found under the folder, C:\Windows\System32\ApplicationServerExtensions\Microsoft.ApplicationServer.ServiceHost.exe, and it must be started in order to capture and dump the events in the configured IBulkCopy provider.
In addition, if you want to correlate all the service calls within a single execution (For example, Service A calling Service B, and B calling C) under a unique global identifier, so you can group all the events under that identifier, there is a new <endToEndTracing> element under the <system.ServiceModel/diagnostics> section that you can use.
<system.ServiceModel>
<diagnostics etwProviderId="7d98f890-ff8d-4311-be4f-e679103ba7cf">
<endToEndTracing propagateActivity="true" messageFlowTracing="true" />
</diagnostics>
</system.ServiceModel>
For example, the following image shows two events that are correlated under the same E2EActivityId, which represents a service “HelloWorld” calling an operation in another “EchoService” service.

WS-Trust 1.4 introduced a new feature called as “ActAs” for addressing common scenarios where an application needs to call a service on behalf of the logged user or a service needs to call another service on behalf of the original caller. These are typical examples of what is usually resolved with the “Trusted Subsystem” pattern.
“ActAs” is not more than a new element in the RST message for including additional information about the original caller when a token is negotiated with the STS for consuming the final service in the Relying Party (that means that a trust relationship already exists between the STS and the final service). That element usually takes the form of a token with identity claims, which are secured (encrypted/signed) and included together with the credentials of the client application that is negotiating the token with the STS.
As this element is part of the WS-Trust specification, it only makes sense in scenarios where the client authentication is delegated to an STS. I already discussed this scenario several times in the past. The following message shows how this element is included in a RST message,
<trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<tr:ActAs xmlns:tr="http://docs.oasis-open.org/ws-sx/ws-trust/200802">
<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_cf5f224e-4bae-4f2d-9800-248023ac0e4d" Issuer="PassiveSTS" IssueInstant="2010-01-04T15:20:14.506Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:Conditions NotBefore="2010-01-04T15:20:14.470Z" NotOnOrAfter="2010-01-04T16:20:14.470Z"></saml:Conditions>
<saml:AttributeStatement>
<saml:Subject>
<saml:NameIdentifier Format="uid:0@stonehenge.comhttp://schemas.xmlsoap.org/claims/UPN">uid:0@stonehenge.com</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Attribute AttributeName="role" AttributeNamespace="http://microsoft">
<saml:AttributeValue>staff</saml:AttributeValue>\
</saml:Attribute>
</saml:AttributeStatement>
<saml:AuthenticationStatement AuthenticationMethod="http://microsoft/geneva" AuthenticationInstant="2010-01-04T15:20:14.481Z">
<saml:Subject>
<saml:NameIdentifier Format="uid:0@stonehenge.comhttp://schemas.xmlsoap.org/claims/UPN">uid:0@stonehenge.com</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
</saml:AuthenticationStatement>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
</ds:Signature>
</saml:Assertion>
</tr:ActAs>
<trust:ComputedKeyAlgorithm>http://docs.oasis-open.org/ws-sx/ws-trust/200512/CK/PSHA1</trust:ComputedKeyAlgorithm>
</trust:RequestSecurityToken>
If you still want to support an scenario like this when an STS is not involved for client authentication, the closer thing you can find is the client authentication through supporting tokens method. I described this scenario in this post, and Dominick did a better job giving a concrete implementation in WCF that uses an Username Token as supporting token, a also a SAML token, which represents something very useful.
The images illustrate two scenarios where this new feature makes a lot of sense. Let’s discuss both of them more in detail.
Scenario 1: A Service A calling a Service B
In this scenario, we have a Service A that needs to make a call to an operation in the Service B. Both services are expecting an token issued by an STS that they trust (The example assumes that they both trust the same STS). This is how “ActAs” works in this scenario.
1. The client negotiates a SAML token with the STS for consuming the service A
2. The client invokes an operation in the Service A using the SAML token it got from the STS as client credentials.
3. Now, the Service A needs to invoke an operation in the Service B so it has to negotiate a new SAML token from the STS first. In order to do that, it includes the SAML token sent by the client as part of the ActAs element, and secures the message using any of the traditional WS-Security profiles. For example, Mutual Certificate, a client certificate for authenticating the client (Service A) and a service certificate for authenticating the service and protecting the messages. The STS issues a new token for consuming the service B using all the information received in the RST message.
4. The service A invokes an operation in the Service B using the SAML token it just got from the STS as client credentials.
Scenario 2: A Web Application calling a Service
In this scenario, the Web Application authenticates all its user through an STS that implements the WS-Trust passive profile. This means that the web application is a claim-aware application that receives the user identity as claims from a token sent by the STS (The user first authenticates in the STS, step 1). As the web application already has a token with the user claims, which is the token it received from the passive STS, it can include it as the ActAs element when it negotiates a SAML token from the Active STS (step 2). Once the application gets a SAML token from the Active STS, it can actually use it for consuming the service (step 3)
Fortunately, WIF already includes support in the client API for negotiating a token with the ActAs element, and also support for parsing and getting access to that information in the STS implementation. What’s more, the implementation of this new feature in WIF is totally interoperable with other Service stacks as well. This is something that have been proved in the Apache Stonehenge project by proving an example application that shows different interoperability scenarios with claim-based security with other service stacks like Sun Metro or WOS2.
On the client side, WIF provides a couple of extensions methods in the WCF channel for including a token in the ActAs element.
public static T CreateChannelActingAs<T>(this ChannelFactory<T> factory, SecurityToken actAs);
public static T CreateChannelActingAs<T>(this ChannelFactory<T> factory, EndpointAddress address, SecurityToken actAs);
public static T CreateChannelActingAs<T>(this ChannelFactory<T> factory, EndpointAddress address, Uri via, SecurityToken actAs);
In case you are using a SAML token, you need to negotiate it out of band with the WSTrustChannel class or use the one that is available in the web application when passive authentication is used with an STS (and the setting saveBootstapTokens is enabled in the microsoft.IdentityModel section). The following code illustrates a sample that uses the SAML token available as part of the Bootstrap tokens in the IClaimsPrincipal instance attached to the current thread.
SecurityToken callerToken = null;
IClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal as IClaimsPrincipal;
if (claimsPrincipal != null)
{
foreach (IClaimsIdentity claimsIdentity in claimsPrincipal.Identities)
{
if (claimsIdentity.BootstrapToken is SamlSecurityToken)
{
callerToken = claimsIdentity.BootstrapToken;
break;
}
}
}
var channel = channelFactory.CreateChannelActingAs(callerToken);
The STS implementation can get the ActAs element information from the RequestSecurityToken.ActAs property,
if (request.ActAs != null)
{
IClaimsIdentity actAsIdentity = new ClaimsIdentity();
CopyClaims(request.ActAs.GetSubject().First(), actAsIdentity);
// Find the last delegate in the actAs identity
IClaimsIdentity lastActingVia = actAsIdentity;
while (lastActingVia.Actor != null)
{
lastActingVia = lastActingVia.Actor;
}
// Put the caller's identity as the last delegate to the ActAs identity
lastActingVia.Actor = outputIdentity;
// Return the actAsIdentity instead of the caller's identity in this case
outputIdentity = actAsIdentity;
}
The apache stonehenge application or the Fabrikam shipping sample in codeplex are using this feature, so you might be interested in taking a look there.
WIF will be finally supported in W2k3. This has represented a big barrier for the adoption of WIF in one of my customers for a while, but it looks like now I will able to use it after December :). This is the official announcement made by the Geneva Team this weekend on their blog,
“Windows Identity Foundation support for Windows Server 2003 SP2 is coming in December 2009. This package will be in English (en-US) and six other languages: German (de-DE), Spanish (es-ES), French (fr-FR), Italian (it-IT), Dutch (nl-NL), and Japanese (ja-JP). Stay tuned for further updates!”
The first chapter of the WCF extensibility guide that Jesus and I have been working on during the last few months went live in MSDN this weekend. You can find it here, http://msdn.microsoft.com/en-us/library/ee672186.aspx
The first chapter gives an overview of the channel layer, and some of the extensibility points you can find there to implement custom channels.
Enjoy!!
I was wondering these days what would be the point in using WS-Passive when there is another simple sign-on solution, OpenID, that works really well and it’s getting a great adoption in the community. I can not say the same about WS-Passive, I haven’t seen any concrete implementation yet (For instance, Microsoft is planning to release a first implementation as part of the WIF framework before the end of this year).
However, I reached the conclusion that both technologies are prepared for addressing different scenarios. For me, OpenID is more suitable for community or social networking web sites that expect to have a great number of users, and can benefit from using the large user databases that some of the existing OpenID providers already have. This is also a great thing for the final user as he can reuse his public OpenID identifier to log into all these web sites.
On the other hand, WS-Passive seems to work better for enterprise scenarios in companies that might have some sort of security infrastructure in place (Customer user databases, active directory, active STSs for services) and do not want to have third parties (other than the parties involved in the business) to participate in the business transactions or to share their user databases with these parties. This is closely related to one of the identity laws that Kim Cameron announced a time ago. Law #3, “Justifiable Parties”, Digital identity systems must be designed so the disclosure of identifying information is limited to parties having a necessary and justifiable place in a given identity relationship.
This was one of the big failures in the adoption of Passport as Single-Sign-On technology. Some relying parties did not understand the purpose of having Microsoft (and Passport) involved in their business transactions.
In addition, WS-Passive only specifies a way to interchange a security token with user claims between the involved parties (Client, STS and Relying Party), so it provides the flexibility of using any security token profile. The most common token profile used today is SAML, as it can be customized with custom assertions or claims specific to the business. OpenID also specifies a way to exchange custom data (other than Simple Registration or SReg data) through the “Attribute Exchange” spec. However, it looks like many of the existing relying parties or identity providers do not support this spec as it is discussed here.
I am just guessing :). What do you think ?.
As Dr Nick announced in this post, WCF 4.0 will ship with a new feature to configure a client channel from a configuration source other than the traditional section in the application configuration file (I discussed a workaround for doing the same thing in WCF 3.0 a time ago in this post)
This will provide the flexibility to deploy some binaries with the client proxies together with an independent configuration file (which might be a resource file, a stand alone file included with your application or something you can download from an specific place), so the main configuration file does not need to be touched at all.
A new channel factory “ConfigurationChannelFactory” is included as part of the System.ServiceModel.Configuration namespace to create channels from an alternative configuration source.
var fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "otherFile.config";
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var factory = new ConfigurationChannelFactory<IService1>("BasicHttpBinding_IService1", configuration, new EndpointAddress("http://localhost:49187/Service1.svc"));
var client = factory.CreateChannel();
var s = client.GetData(3);
Console.WriteLine(s);
The file “otherFile.config” is just a simple configuration file that contains the client definition and configuration for using the “IService1” service.
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" >
<security mode="None">
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:49187/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
All this code is based on the .NET 4.0 beta 1, so it might change in the final release.
The other day I came across a pretty cool project, Linq2Twitter, that basically implements a linq provider for consuming the Twitter REST Api. This project is not only interesting because it provides an intuitive model for incorporating Twitter calls into any existing application, but also because it shows how to use the OAuth authentication mode that the Twitter Api supports.
As it is common with other linq providers, this library provides a root class “TwitterContext” for executing queries or calling other services in the API.
So you can do things like this,
var twitterCxt = new TwitterContext();
var tweets =
from tweet in twitterCtx.Status
where tweet.Type == StatusType.Friends
select tweet;
tweets.ToList().ForEach(
tweet => Console.WriteLine(
"Friend: {0}\nTweet: {1}\n",
tweet.User.Name,
tweet.Text));
The example above shows some code to gets the status of all your friends.
Before using any of the services available in the API, you must first authenticate in Twitter using either basic authentication (The traditional way with username and password) or OAuth. The authentication mode is specified in the twitter context.
In case you decide to go with OAuth, it is very simple to use. You only need to provide the OAuth secret and key associated to an application that you previously registered in Twitter.
Console.Write("Consumer Key: ");
twitterCtx.ConsumerKey = Console.ReadLine();
Console.Write("Consumer Secret: ");
twitterCtx.ConsumerSecret = Console.ReadLine();
string link = twitterCtx.GetAuthorizationPageLink(false, false);
Console.WriteLine("Authorization Page Link: {0}\n", link);
Console.WriteLine("Next, you'll need to tell Twitter to authorize access. This program will not have access to your credentials, which is the benefit of OAuth. Once you log into Twitter and give this program permission, come back to this console and press Enter to complete the authorization sequence.\n\nPress Enter now to continue.");
Console.ReadKey();
// launches browser so you can log in and give permissions
Process.Start(link);
Console.WriteLine("\nYou should see your browser navigate to Twitter, saying that your application wants to access your Twitter account. Once you've authorized this program, return to this console and press any key to execute the LINQ to Twitter code.");
Console.ReadKey();
var uri = new Uri(link);
NameValueCollection urlParams = HttpUtility.ParseQueryString(uri.Query);
string oAuthToken = urlParams["oauth_token"];
twitterCtx.RetrieveAccessToken(oAuthToken);
if (twitterCtx.AuthorizedViaOAuth)
OAuth requires a browser session so you can log into twitter and authorize the client application to get your data. This is not a problem if the client application is a web application, the authentication and authorization processes flow very natural. However, in the case of Windows or Console Application, a browser instance needs to be created, this is what the example above is doing in the line “Process.Start”. If you are already authenticated in twitter, you will see this page where you need to authorize the application that wants to get access to your data.
It looks like Andrew Arnott have been involved in the OAuth implementation for this library, which is a really good thing since he is the main contributor in two of the most stables projects for OpenID (DotNetOpenId) and OAuth (DotNetOpenAuth) in the .NET world.
El proximo sabado 26 de septiembre vamos a tener la oportunidad de tener nuevamente un codecamp en buenos aires de la mano de Microsoft.
El evento como en otras oportunidades va a ser mas que interesante, con un monton de charlas prometedoras y algunas novedades que Microsoft tiene para darnos.
Para mas informacion, podes visitar el sitio oficial en
http://www.codecamp.com.ar/
Los esperamos a todos.
In the previous post, I discussed how bad was to expose EF entities directly as data contracts from a perspective of “interoperability”. This also revealed a lot of internal implementation details about EF that the client applications should not worry about.
As Daniel Simmons pointed out, the next version of Entity Framework (4.0) will ship with a new and very useful feature to represent the data entities using POCOs (Self-tracking entities). This new support for POCOs will make possible to simplify a lot the final representation of entities on the wire, hiding all those annoying details about EF. You will also able to decorate the entities with DataContract/DataMember attributes if you do not want to expose the whole entity in the service.
However, I still do not buy the idea of using the EF entities as data contracts. By doing that, you are coupling your service interface to the final data model, which is not a good idea since both layers usually evolve at different rates. What is worse, any change in the database model might affect your service interface as well, breaking the contract that any potential consumer have with the service.
This last aspect is related to versioning. The versioning between the two layers is completely different, you might have for instance an User entity in the data model, and different versions of the same entity in the service interface, UserV1, UserV2, etc (Any of these corresponding to a different version of the service). The service is the responsible of making the transition between the different data contracts to the final data model entities.
I think this might be only useful for RIA applications where you use the services as a mechanism to interchange data between your backend layer and the UI, for instance web applications that use Ajax Callbacks or Silverlight applications. So, the number of potential consumers of the services is really low.
A common misconception is to think that a WCF proxy can be used and disposed as any other regular class that implements IDisposable. However, the IDisposable implementation in the WCF client channel is not like any other, and it can throws exceptions. A phrase I got from this thread in the WCF forum will give you a better context about this scenario,
“I think a key thing to notice is that Close() often implies doing "real work" that may fail, including network communication handshakes to shutdown sessions, committing transactions, etc.”
As consequence of this, we should add some code to handle any possible exception for network errors when a proxy is closed/disposed.
The common pattern for cleaning up a proxy is the following,
try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}
The problem is, I do not want to have that code everywhere in my application. A good solution for that is to use a helper class like this one.
Michelle recently announced a new project that automatically generates a proxy helper class like that in Visual Studio. http://wcfproxygenerator.codeplex.com/
That is a feature I would like to see out of the box in the next version of WCF :).
More Posts
Next page »