Share via


Authenticated messaging in WF 4

Authenticated messaging is one limitation in WF 4 as currently there is no API for setting up credentials to be used with a Send activity. Having said that, ChannelFactory used by Send activity still picks up the behaviour configuration from the config file.

So you can potentially write a custom behaviour to supply additional credentials to the Send activity. Let’s see a simple clientCredentialsAdapter behaviour which will enable you to setup userName/Password in config file. It’s almost always a bad idea to keep unencrypted password in config files so it is recommended that you should use config encryption to encrypt the behaviour section.

<behavior name="credentialAdapter">

  <clientCredentials>

    <serviceCertificate>

      <authentication certificateValidationMode="None"/>

      <defaultCertificate findValue="f7ad5a9dcc35f21ffc691925515f48eb44f5e07a" x509FindType="FindByThumbprint" storeLocation="CurrentUser" storeName="My"/>

    </serviceCertificate>

  </clientCredentials>

  

  <clientCredentialsAdapter>

    <userName userName="configUser" password="p@ssw0rd!"/>

  </clientCredentialsAdapter>

</behavior>

At this point, you can configure this behaviour on an endpoint used by a Send activity. This change will enable Send activity to use this userName/Password for securing outgoing messages.

public class ClientCredentialsAdapterBehavior : IEndpointBehavior

{

    ClientCredentialsAdapterBehaviorElement configElement;

    public ClientCredentialsAdapterBehavior(ClientCredentialsAdapterBehaviorElement configElement)

    {

        this.configElement = configElement;

    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){}

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)

    {

        var clientCredentials = endpoint.Behaviors.Find<ClientCredentials>();

        Adapt(clientCredentials);

    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

    public void Validate(ServiceEndpoint endpoint){}

    void Adapt(ClientCredentials orignalCredentials)

    {

        orignalCredentials.UserName.UserName = configElement.UserName.UserName;

        orignalCredentials.UserName.Password = configElement.UserName.Password;

    }

}

So that was simpleJ What about a scenario where you have userName/Password as part of workflow state and you want to use that instead?

Well, in that case there is more work involved which I’ll discuss in next post.

Originally posted by Zulfiqar on the 19th of January 2010 here.