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
