Zulfiqar's weblog

Architecture, security & random .Net

Archive for April, 2010

Configuring SAML Assertion Subject Name and Format for a WIF STS

Posted by zamd on April 27, 2010

In some interop scenarios, subject name and its format needs to be included in the Saml token/assertion generated by the STS. You can easily configure a WIF based STS to generate this by adding a NameIdentifier claim and by settings it’s format property.

protected override IClaimsIdentity GetOutputClaimsIdentity(IClaimsPrincipal principal,

    RequestSecurityToken request, Scope scope)

{

    var nameIdentifierClaim = new Claim(ClaimTypes.NameIdentifier, "me@zamd.com");

    nameIdentifierClaim.Properties[ClaimProperties.SamlNameIdentifierFormat] = "EMAIL";

 

    return new ClaimsIdentity(

        new Claim[]

        {

            new Claim(System.IdentityModel.Claims.ClaimTypes.Name, "Zulfiqar"),

            nameIdentifierClaim

        });

 

This generates following Saml Assertion where you can see the generated NameIdentifier & format attribute.

 <saml:AttributeStatement xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
   <saml:Subject>
    <saml:NameIdentifier Format="EMAIL">me@zamd.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="name" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
    <saml:AttributeValue>Zulfiqar</saml:AttributeValue>
  </saml:Attribute>
</saml:AttributeStatement>

Posted in WIF | 1 Comment »

Messaging activities intricacies

Posted by zamd on April 26, 2010

WF 4 introduced messaging activities which provides a visual way of creating web services and their clients.  In VS 2010 when you do “Add Service Reference” (in a workflow project), the wizard automatically generates activities and config in contrast to imperative code and config (the legacy way J). This looks cool as you can simply drag & drop these activities on a workflow surface and use them to consume your web services.  But how does these activities lay themselves on top of WCF ChannelFactory/Channel API?

Send activity is a wrapper around WCF ChannelFactory/Channel API and there is a cache layer built into Send activity’s infrastructure as well. By default, this caching layer is only used in a safe caching mode, where Endpoint information is specified using the properties of Send activity and you are using one of the stock Bindings without any modifications. As soon as you load Binding information from the config (regardless if you have changed the binding or not) safe caching will be disabled.

Without caching, default WSHttpBinding is not suitable for workflow scenarios as it will negotiate credentials (which is a 2 legs handshake) & then establish a secure conversation session (another leg). But then this would be only be used for a single message and needs to be done for every message generated by the Send activity. In my simple example, I have following service which is using default wsHttpBinding and I used VS “Add Service Reference” to generate a client.

clip_image002

The wizard has generated following two activities and along with some default config (default wsHttpBinding)

clip_image004

I then used these activities to craft a basic client which looks like this:

clip_image006

With this simple arrangement my message flow looks this: For Operation1 calls, following 4 infrastructure messages are generated. Note these are request-reply message so each of them has reply message too.

http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue

http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue

 

http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT

 

http://tempuri.org/IService/Operation1

http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Cancel

By default, wsHttpBinding  is optimized for security and performance – so it establishes a secure conversation which has an upfront cost but applying security for subsequent messages is much cheaper. But unfortunately, in workflow world we only transmit one message as part of secure session, as the second call would use a brand new factory, and all of this will be done again.

Now you can argue here that your binding is still the same default wsHttpBinding binding, why messaging activities didn’t use channel factory caching in this case.  As binding information is now coming from the configuration file, messaging activities can’t safely determine that you are using the default binding hence caching is disabled.  If you know for sure that you binding is still secure for sharing (as in this case, it was the same default wsHttpBinding) you can enable UnsafeCaching which will then reuse the ChannelFactory for sending messages to the same endpoint. Caching API is exposed via SendMessageChannelCache class, which can be added as an extension into your Workflow Host.

class Program

{

    static void Main(string[] args)

    {

        var invoker = new WorkflowInvoker(new Workflow1());

 

        var cache = new SendMessageChannelCache { AllowUnsafeCaching = true, };

        invoker.Extensions.Add(

            delegate

            {

                return cache;

            }

            );

        invoker.Invoke();

        cache.Dispose();

    }

}

 

In above example, cache is added as an Instance level cache (notice I’m using Func<> delegate). Cache can be shared at different scopes; Host & AppDomain are the other two options.  With above modification you would get the expected behaviour:

Secure conversation session is established at the start and would be used to secure all subsequent messages to the same endpoint.

Remember, you are now getting sessions on the server side and you would have to explicit close those sessions otherwise they will stay hanging and will ultimately saturate your session throttles.

You can close the active sessions by disposing the cache. This will send the Cancel message to the sessions.

 

http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Cancel

Please note, this is just one example of optimizing the messaging when using workflow services activities.

Posted in WF4 | Tagged: | 1 Comment »

Custom ServiceHostFactory for a XAMLX based Service

Posted by zamd on April 23, 2010

For IIS/WAS hosted services backed by a physical .SVC file (WCF 3.0/3.5) you can specify a custom ServiceHostFactory in the .svc file as part of service specification. There is no such declaration for XAMLX files and instead you can use config-based activation feature to achieve the same result.

If my WCF service is deployed as Service1.xamlx and I want to customize the WorkflowServiceHost before it’s opened and used, I can easily do this using following two steps:

  1. Create a custom ServiceHostFactory by sub classing the default one

namespace DeclarativeServiceLibrary1

{

    public class MyServiceHostFactory : WorkflowServiceHostFactory

    {

        protected override WorkflowServiceHost CreateWorkflowServiceHost(Activity activity, Uri[] baseAddresses)

        {

            return base.CreateWorkflowServiceHost(activity, baseAddresses);

        }

        protected override WorkflowServiceHost CreateWorkflowServiceHost(WorkflowService service, Uri[] baseAddresses)

        {

            var host =  base.CreateWorkflowServiceHost(service, baseAddresses);

            // add your customizations here…

            return host;

        }

    }

}

2.  Configure your custom ServiceHostFactory for your XAMLX file

  <system.serviceModel>

  

    <serviceHostingEnvironment multipleSiteBindingsEnabled=true >

      <serviceActivations>

        <add relativeAddress=~/Service1.xamlx

             service=Service1.xamlx

             factory=DeclarativeServiceLibrary1.MyServiceHostFactory/>

      </serviceActivations>

    </serviceHostingEnvironment>

  </system.serviceModel>

Posted in WCF | 6 Comments »