Share via


PrincipalPermission Authorization in WF 4

In last post, I have shown you how to get hold of OperationContext when using messaging activities. Once you got hold of OperationContext, you can use it to perform many useful tasks and one of them is Authorization. Let’s start by defining a Scope activity to hook our IReceiveMessageCallback implementation.

    [Designer(typeof(PrincipalPermissionScopeDesigner))]

    public class PrincipalPermissionScope : NativeActivity

    {

        public InArgument<string> PrincipalPermissionName { get; set; }

        public InArgument<string> PrincipalPermissionRole { get; set; }

        public Activity Body { get; set; }

        protected override void Execute(NativeActivityContext context)

        {

            var name = this.PrincipalPermissionName.Get(context);

            var role = this.PrincipalPermissionRole.Get(context);

            var principalPermission = new PrincipalPermission(name, role);

            context.Properties.Add("AuthorizationManager",

                new AuthorizationManager(principalPermission));

            context.ScheduleActivity(this.Body);

        }

            }

As part of Scope activity execution, I have added my ReceiveMessageCallback in execution properties collection. This enables our callback to be called for every message received by any activity inside the Scope. Once we have access to OperationContext (which is the only as the only parameter of the callback) we can use it to perform authorization.

        [DataContract]

        class AuthorizationManager : IReceiveMessageCallback

        {

            [DataMember]

            PrincipalPermission principalPermission;

            public AuthorizationManager(PrincipalPermission principalPermission)

            {

                this.principalPermission = principalPermission;

            }

            public void OnReceiveMessage(

                System.ServiceModel.OperationContext operationContext,

                ExecutionProperties activityExecutionProperties)

            {

                var currentPrincipal = Thread.CurrentPrincipal;

                var isPrincipalSet = false;

                var targetPrincipal = GetPrincipal(operationContext);

                try

                {

                    if (targetPrincipal != null)

                    {

                        Thread.CurrentPrincipal = targetPrincipal;

                        isPrincipalSet = true;

                        principalPermission.Demand();

                    }

                }

                catch (SecurityException)

                {

                    throw SecurityUtility.CreateAccessDeniedFaultException();

                }

                finally

                {

                    if (isPrincipalSet)

                        Thread.CurrentPrincipal = currentPrincipal;

                }

            }

And with a customer designer, this is how it look like

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