Zulfiqar's weblog

Architecture, security & random .Net

Archive for February, 2010

Introducing Workflow Security Pack

Posted by zamd on February 23, 2010

Have you already started serious development with WF 4 and found security limitations?

Have you struggled to implement authenticated messaging, claims-based security, role-based security and other security features in workflow solutions?

WF 4 is a highly extensible framework so most of these features can be built using the WF extensibility model, but wouldn’t it be nice to have all of these security features available in an easy to use activity library?

 

Here comes the Workflow Security Pack (WFSP) project… WFSP is a collection of activities and associated plumbing to enable key security scenarios in WF 4.  WFSP activities blend with the rest of the WF to bring end-to-end integrated security into workflow solutions. The following diagram shows the initial set of activities which are part of WFSP.

cid:image001.jpg@01CAB458.185E10A0 

Following are some of the scenarios enabled by WFSP:

1.      Authenticated messaging

a.      Enables the use of various credentials with Send activity

b.      Follows exactly the same model when using a Username token or a Saml token issued by an STS

2.      Role-based security

a.      Enables principal permission based authorization on the Receive activity

b.      Supports standard RoleProvider extensibility model

3.      Claims-based security

a.      Ability to acquire a SAML token using the WS-Trust protocol

b.      Ability to pass this token to a SAML secured service using WS-Security

4.      End-to-end Claim-based delegation

a.      Ability to use any token as an ActAs token

5.      Transparent handling of tokens in a long-running environment

a.      Enlisted tokens are preserved during persist and reload cycles

6.      Impersonation and Delegation support

a.      Ability to impersonate incoming Identity on Receive side

b.      Ability to impersonate a User identity on the Send side

c.      Ability to call a backend service from the Impersonated scope (Kerberos delegation)

7.      WCF OperationContext access in a thread-agnostic way

 

In future posts, I’ll take an in-depth look into each of activities above and various scenarios enabled by these activities. Stay tuned.

 

 

Posted in WF4, WFSP | 10 Comments »

Adding Dynamic methods to a WCF Service

Posted by zamd on February 5, 2010

Someone asked me if it’s possible to add a Ping method to every service contract without repeatedly defining it in each service contract?  The answer is yes & and it’s fairly simply too.

Here I have a LoginService, which require that implicit Ping method (DateTime Ping(){})like all other service.

 

[ServiceContract]

class LoginService

{

    [OperationContract]

    public bool Login(string userName, string password)

    {

        return true;

    }

}

This is how you would configure your host for these implicit methods.

class Program

{

    static void Main(string[] args)

    {

        var sh = new ServiceHost(typeof(LoginService), new Uri(http://localhost:9001″));

 

        GeneratePingMethod(sh);

        sh.Open();

 

        Console.ReadLine();

        sh.Close();

    }

}

 

Please note “GeneratePingMethod” adds the Ping method to every endpoint.  I’m simply creating the operation using the WCF description API and adding it into the description tree. PingImplementationBehavior plugs in a custom OperationInvoker which calls the actual Ping implementation.

 

private static void GeneratePingMethod(ServiceHost sh)

{

    foreach (var endpoint in sh.Description.Endpoints)

    {

        var cd = endpoint.Contract;

        var od = new OperationDescription(“Ping”, cd);

        var inputMsg = new MessageDescription(cd.Namespace + cd.Name + “/Ping”, MessageDirection.Input);

        var outputMsg = new MessageDescription(cd.Namespace + cd.Name + “/PingResponse”, MessageDirection.Output);

        var retVal = new MessagePartDescription(“PingResult”, cd.Namespace); ;

        retVal.Type = typeof(DateTime);

 

        outputMsg.Body.ReturnValue = retVal;

 

 

        od.Messages.Add(inputMsg);

        od.Messages.Add(outputMsg);

 

        od.Behaviors.Add(new DataContractSerializerOperationBehavior(od));

        od.Behaviors.Add(new PingImplementationBehavior());

 

        cd.Operations.Add(od);

    }

}

 

class PingImplementationBehavior : IOperationBehavior

{

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)

    { }

 

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)

    { }

 

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)

    {

        dispatchOperation.Invoker = new PingInvoker();

    }

 

    public void Validate(OperationDescription operationDescription)

    { }

}

Again a fairly simple invoker which is tightly coupled to the signature of Ping method.

class PingInvoker : IOperationInvoker

{

    public object[] AllocateInputs()

    {

        return new object[0];

    }

 

    public object Invoke(object instance, object[] inputs, out object[] outputs)

    {

        outputs = new object[0];

        return Ping();

    }

 

    public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)

    {

        throw new NotImplementedException();

    }

 

    public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)

    {

        throw new NotImplementedException();

    }

 

    public bool IsSynchronous

    {

        get { return true; }

    }

 

    public static DateTime Ping()

    {

        return DateTime.Now;

    }

}

Posted in WCF | 8 Comments »

 
Follow

Get every new post delivered to your Inbox.