July 2010 - Posts

Centralizing and simplifying WCF configuration with SO-Aware

It's not a secret that WCF configuration management is one of the biggest challenges that companies face when adopting WCF as part of their enterprise solutions. Whether the declarative capabilities of the WCF programming model enable a great level of flexibility to WCF solutions they can also become a nightmare from the management standpoint. This shouldn't come as a big surprise, just imaging managing the security configuration of a few dozen WCF services across different environments (DEV, QA, PROD) and you will get pretty close to a headache ;)

The release of .NET Framework 4.0 introduced various improvements in the WCF configuration model by moving some of the default binding and behaviors configurations to the machine.config file. Whether this simplifies the development experience, its not a practical solution for medium to large size WCF solutions on which the default bindings are not sufficient to address the capabilities of the service.

SO-Aware introduced a very creative model to simplify the configuration of WCF service by combining a centralized configuration repository, the goodness of OData and the flexibility of the WCF extensibility model. The first important feature SO-Aware introduces is the ability to categorize bindings and behaviors as part of our centralized repository. The following figure helps to illustrate that concept.

Config[1]

To make things even simpler, SO-Aware launches with a number of preconfigured bindings and behaviors that model some of the most common WCF scenarios. This capability allow users to reuse the same binding and behavior configurations across different services. The process of configuring a service is as simple as selecting the preconfigured binding or behavior as illustrated in the following figure.

Bindings[1]

It is important to highlight that every single artifact of the service configuration can be accessed using an REST OData API via a HTTP GET.

After configuring the services in the SO-Aware portal we are ready to see the magic happen. SO-Aware includes a custom service host that, in a nutshell, resolves the service configuration from the SO-Aware repository and applies it to the target WCF service. This model not only drastically simplifies the configuration experience but it also enforces consistency on the bindings and behaviors applied to the different services. The following code illustrates the configuration experience using SO-Aware.

   1: <serviceRepository
   2:        url="http://<my web server>/SOAwarePortal/ServiceRepository.svc">
   3:     <services>
   4:         <service name="ref:CRMSOAPService(1.0)@dev" 
   5:                  type="Tellago.ServiceModel.Governance.Samples.CRMSOAPService, 
   6:                        Tellago.ServiceModel.Governance.Samples.SOAPServices"/>
   7:     </services>
   8: </serviceRepository>

In order for this model to work, the service must use a custom service host included in the SO-Aware bits.

   1: <%@ ServiceHost Language="C#" Debug="true" 
   2:  Service="Tellago.ServiceModel.Governance.Samples.CRMSOAPService"
   3:  Factory="Tellago.ServiceModel.Governance.Hosting.ConfigurableServiceHostFactory,
   4:           Tellago.ServiceModel.Governance.Hosting"  %>

As you can see, developers will only have to declare the main URI of the SO-Aware endpoint as well as the service version that needs to be configured. The simplicity of this model drastically contrasts with the traditional WCF experience on which the complete set of WCF configuration artifacts need to kept in the configuration file.

This model also enables architects to change or modify the service configuration using the centralized console without having to replicate the change on all the service configuration files.

On the client side, SO-Aware also provides an elegant programming model that enables applications to dynamically resolve the configuration from the main repository without the need to keeping a local configuration file. The following code illustrates that concept.

   1: ConfigurableProxyFactory<ICRMServiceChannel> factory = 
   2: new ConfigurableProxyFactory<ICRMServiceChannel>(ServiceUri,
   3:                               "CRMSOAPService(1.0)", "dev");
   4: ICRMServiceChannel service= factory.CreateProxy();
   5: var accounts= service.GetAccounts();

Similarly to the service programming model, the client application can resolve the configuration for a specific service by using the ConfigurableProxylFactory class. Additionally, the client application can resolve specific WCF artifacts such as bindings or behaviors by using the same programming model. The following code illustrates the steps needed to resolve a behavior that contains the certificate credentials needed to invoke a specific WCF service.

   1: factory.Endpoint.Behaviors.Remove<ClientCredentials>();
   2: factory.Endpoint.Behaviors.Add(resolver.ResolveEndpointBehavior
   3:                     ("ClientCredentialsBehavior").Behaviors[0]);

I hope this examples clearly illustrate how SO-Aware can drastically simplify the configuration of WCF services and client and, at the same time, enforce consistency and enable the management of configuration artifacts across the entire SOA infrastructure. SO-Aware uses this model internally to enforce other behaviors such as monitoring or testing which will be subject of future posts.

Tellago Studios is here!!!

Today is a special day for us. After two years of steadily growing Tellago, we have decided to launch a new company to focus on building enterprise software. In principle the idea is very simple, we want to translate the lessons we have learned in our continuous work with customers into enterprise software solutions that reflect the latest architecture and technology best practices and at the same time remain simple and practical to use.

At Tellago, we have a passion for innovation and we are very proud of having built a team that includes some of the top thought leaders in the developer communities. Many of us serve as advisors to software companies such as Microsoft or Oracle which put us on a unique position to effectively leverage the latest technologies in our daily work with customers. However, technology expertise and passion for innovation are not sufficient to build effective software and we try to complement elements with the lessons we have learned when applying these technologies in some of the largest and most complex IT environments in the world. Our first product, SO-Aware™, is a perfect example of an effort that combines technology expertise, passion for innovation and being very receptive to the realities faced by customers in the real word enterprise.

SO-Aware?

SO-Aware is a Web Services repository that enables the cataloging, management, monitoring and testing of Web Services. Contrasted against the complexity of traditional UDDI-centric SOA governance products, SO-Aware uses a simple and unique design based on the principles of REST and OData which enables the manipulation of service artifacts using standard http verbs like GETs or POSTs. Whether SO-Aware can manage Web Services developed on any technology stack, it excels in the management of Windows Communication Foundation (WCF) solution enabling capabilities that are very needed in enterprise SOA-WCF solutions. Specifically, the first version of SO-Aware focuses on the following aspects:

· Service cataloging: SO-Aware provides the infrastructure to organize different versions of web services using a simple category-based taxonomy. SO-Aware extends these capabilities beyond traditional SOAP services by supporting REST and OData  services.

· Centralized configuration management: SO-Aware provides a creative model for the centralization and configuration of WCF services and endpoints that removes the need for maintaining large and complex configuration files. Additionally, SO-Aware facilitates the modeling and creating of configuration artifacts such as bindings or behaviors in a way that is accessible to non-WCF  experts.

· Testing: The first release of SO-Aware includes a sophisticated testing subsystem that enables the testing of WCF services. The tests created using SO-Aware can either be executed on-demand using the management portal or periodically using the test scheduling system. Additionally, SO-Aware tracks the execution of tests and enables specific analytics that help testers and members of IT operations teams accurately monitor the behavior of the  tests.

· REST-OData API: SO-Aware is 100% OData centric. In that sense, every capability of SO-Aware from service cataloging to testing is accessible through simple HTTP interfaces using OData as the encoding mechanism.

· Service activity monitoring: SO-Aware enables a simple model for tracking the message flow for the various services in your SOA. Using this information, SO-Aware provides specific analytics that help to accurately describe the runtime behavior of services.

· Dependency modeling: Services that depend on other services are very common in SOA environments. SO-Aware enables developers and architects to model the dependencies between services using a simple visual interface included in the management  portal.

· Management Portal: SO-Aware is 100% OData centric. In that sense, every capability of SO-Aware from service cataloging to testing is accessible through simple HTTP interfaces using OData as the encoding mechanism.

· PowerShell provider: SO-Aware can be completely managed using a scripting environment based on Windows PowerShell. The current version of SO-Aware includes a PowerShell provider that contains a large number of commands that abstract the different SO-Aware capabilities.

Community Centric

We at Tellago Studios are firm believers in the power of the developer community to drive the success or failure of software technologies. Consequently, we are committed to make the developer community an integral part of every software solution at Tellago Studios. With SO-Aware, we have spent the last few weeks demoing to some of the most influential developers in the WCF community as well as members of the Microsoft product team. To reaffirm this commitment, WE ARE MAKING THE EXPRESS EDITION OF SO-AWARE AVAILABLE FOR FREE!!! This is a feature-complete release limited to five services. By making this edition of SO-Aware available, we are encouraging the WCF community to try SO-Aware and give us valuable feedback about what to improve on the next version.

Where I can find more information about SO-Aware?

A good first step to learn more about SO-Aware is to watch some of our knowledge based videos at http://tellagostudios.com/videos. This will help you to get a feeling for the capabilities of the products. Additionally, we really encourage you to download the express edition at http://tellagostudios.com/download to get started. In the next few days, Microsoft will be publishing several videos about SO-Aware as part of Channel9's endpoint TV show http://channel9.msdn.com/shows/Endpoint/. Additionally, you will find regular content about SO-Aware and Tellago Studios at our product blog http://tellagostudios.com/blog.

What's next for Tellago Studios?

The release of SO-Aware is a big milestone for Tellago Studios and we are going to put a lot of energy on improving it based on your feedback. However, by the time you are reading this blog post we should be back working on the design and prototype of our next solutions. As firm believers in the agile and lean software development methodologies, you should expect continuous releases on our different products.

Acknowledgments

During the last few months, SO-Aware evolved from being a prototype to a robust software technology by embracing the invaluable feedback of some of our customers, partners and other members of the development community. Our first thanks has to go to our staff at Tellago that have contributed in a lot of ways to both Tellago Studios and SO-Aware. We are also thankful to a group of our customers who believed in the concept and our ability to execute and who helped to improved the product with their constant feedback. A special mention to our business partners at Pluralsight and other members of the development community or Microsoft product teams who took the time to participate on various demonstrations of SO-Aware as well as brainstorming sessions that contributed to improve the feature set of the product.

I hope you are as excited about SO-Aware as we are. This is hopefully just the start of a long journey for Tellago Studios. Please go to our website, give it a try with our express version and bombard us with your feedback. We are looking forward to hearing from you.

Enabling WIF ActAs via configuration

Identity delegation is one of the most common scenarios in Service Oriented (SO) enterprise infrastructures. Essentially,  this pattern applies to scenarios where the final recipient of the issued token can inspect the entire delegation chain and see not just the client, but all intermediaries to perform access control, auditing and other related activities based on the whole identity delegation chain.

The current version of Windows Identity Foundation (WIF) provides an elegant model for enabling identity delegation by using the WS-Trust ActAs attribute. My colleague and friend Pablo Cibraro posted a great explanation of the ActAs support in WIF.

In a nutshell, a client application can enable an ActAs token by invoking the CreateChannelActingAs operation of the WCF channel factory as illustrated in the following code.

   1: SecurityToken callerToken = null;
   2:  
   3: IClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal as IClaimsPrincipal;
   4: if (claimsPrincipal != null)
   5: {
   6:   foreach (IClaimsIdentity claimsIdentity in claimsPrincipal.Identities)
   7:   {
   8:     if (claimsIdentity.BootstrapToken is SamlSecurityToken)
   9:     {
  10:       callerToken = claimsIdentity.BootstrapToken;
  11:       break;
  12:      }
  13:    }
  14: }
  15:  
  16: channel = factory.CreateChannelActingAs<IMyService>(callerToken);

Despite of the simplicity of the previous approach, it still requires to include the code as part of the client application. However, there is a large number of scenarios on which we would like to abstract that complexity from the developer by enabling a declarative interface via configuration. The current version of WIF only supports enabling the use of the ActAs token programmatically. However after a few minutes of using .NET reflector we can figure out that the we can create an ActAs token using something similar to the following code.

   1: FederatedClientCredentialsParameters parameters = 
   2:                      new FederatedClientCredentialsParameters();
   3: parameters.ActAs = callerToken;
   4: ((IChannel)channel).GetProperty<ChannelParameterCollection>().Add(parameters);

Using the previous techniques, it is not hard to create a WCF client message inspector that attaches an ActAs token to the WS-Trust request as shown in the following code.

 

   1:  
   2: public class ActAsInterceptor : IClientMessageInspector
   3: {
   4:   public void AfterReceiveReply(ref Message reply, object correlationState)
   5:   { 
   6:   }
   7:  
   8:   public object BeforeSendRequest(ref Message request, IClientChannel channel)
   9:   {
  10:     SecurityToken callerToken = null;
  11:    IClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal as IClaimsPrincipal;
  12:    if (claimsPrincipal != null)
  13:    {
  14:      foreach (IClaimsIdentity claimsIdentity in claimsPrincipal.Identities)
  15:      {
  16:        if (claimsIdentity.BootstrapToken is SamlSecurityToken)
  17:        {
  18:          callerToken = claimsIdentity.BootstrapToken;
  19:          break;
  20:        }
  21:      }
  22:    }
  23:    FederatedClientCredentialsParameters parameters = 
  24:                                       new FederatedClientCredentialsParameters();
  25:    if (null != callerToken)
  26:    {
  27:      parameters.ActAs = callerToken;
  28:    try
  29:    {
  30:    ((IChannel)channel).GetProperty<ChannelParameterCollection>().Add(parameters);
  31:    }
  32:      catch (Exception ex)
  33:      {}
  34:    }
  35:    return null;
  36:   }
  37:  
  38:  }
  39: }

We can inject our inspector into the WCF client runtime by creating an endpoint behavior as illustrated in the following code.

   1: public class FederatedIdentityExtensionsBehavior: IEndpointBehavior
   2:  {
   3:  
   4:      public void AddBindingParameters(ServiceEndpoint endpoint, 
   5:                                    BindingParameterCollection bindingParameters)
   6:      {
   7:      
   8:      }
   9:  
  10:      public void ApplyClientBehavior(ServiceEndpoint endpoint,
  11:                                      ClientRuntime clientRuntime)
  12:      {
  13:          clientRuntime.MessageInspectors.Add(new ActAsInterceptor());
  14:      }
  15:  
  16:      public void ApplyDispatchBehavior(ServiceEndpoint endpoint, 
  17:                                       EndpointDispatcher endpointDispatcher)
  18:      {
  19:  
  20:      }
  21:  
  22:      public void Validate(ServiceEndpoint endpoint)
  23:      {
  24:          FederatedClientCredentials item = null;
  25:          ClientCredentials other = endpoint.Behaviors.Find<ClientCredentials>();
  26:          if (other != null)
  27:          {
  28:              endpoint.Behaviors.Remove(other.GetType());
  29:              item = new FederatedClientCredentials(other);
  30:  
  31:              endpoint.Behaviors.Add(item);
  32:          }
  33:      }
  34:  }

After this we can enable our behavior via configuration by implementing a behavior extension element as shown below.

   1: public class FederatedIdentityExtensionsBehaviorElement: BehaviorExtensionElement
   2:     {
   3:         public override Type BehaviorType
   4:         {
   5:             get { return typeof(FederatedIdentityExtensionsBehavior); }
   6:         }
   7:  
   8:         protected override object CreateBehavior()
   9:         {
  10:             return new FederatedIdentityExtensionsBehavior();
  11:         }
  12:     }

After this, our client application can take advantage of the ActAs functionality by configuring our endpoint behavior as illustrated below.

   1: <client>
   2:   <endpoint address="service endpoint"
   3:     contract="ISampleService" 
   4:     binding="customBinding" 
   5:     bindingConfiguration="FederatedBinding" 
   6:     behaviorConfiguration="FederatedBehavior" 
   7:     name="SampleService">
   8:   </endpoint>
   9: </client>
  10:  
  11: <bindings>
  12:   <customBinding>
  13:     <binding name="FederatedBinding">
  14:     <security authenticationMode="IssuedTokenForCertificate" 
  15:       messageSecurityVersion=
  16:       "WSSecurity11WSTrust13...">
  17:       <issuedTokenParameters keyType="SymmetricKey"

18: tokenType=

"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">

  19:       <issuer address="STS URL…." 
  20:       binding="customBinding" bindingConfiguration="stsBinding">
  21:       </issuer>
  22:   
  23:       <issuerMetadata address="STS MEX URL...."/>
  24:       </issuedTokenParameters>
  25:     </security>
  26:     <textMessageEncoding messageVersion="Soap12WSAddressing10"/>
  27:     <httpTransport/>
  28: </binding>
  29: <binding name="stsBinding">
  30: <security authenticationMode="MutualCertificate"
  31:   messageSecurityVersion="WSSecurity11WSTrust13...">
  32:             
  33:  </security>
  34: <textMessageEncoding messageVersion="Soap12WSAddressing10"/>
  35: <httpTransport/>
  36: </binding>
  37: </customBinding>
  38: </bindings>
  39:  
  40: <behaviors>
  41:   <endpointBehaviors>
  42:     <behavior name="FederatedBehavior">
  43:     <clientCredentials>
  44:       Client credentials section...
  45:     </clientCredentials>
  46:  
  47:    <federatedActAs />
  48:     
  49:  </behavior>
  50:  </endpointBehaviors>
  51: </behaviors>
  52: </system.serviceModel>

Using the previous technique, client applications can enable identity delegation scenarios using a 100% declarative approach.

More Posts