Are there proven patterns that anyone could share regarding Workflow 4.0 services integrated with Windows Identity Foundation? We are looking for the best way to inspect the STS token and claims in order to derive who the user is outside the workflow service instance context and make the application’s user object available to the workflow context.
We want to maintain separation of concerns between the service implementation of WIF and workflow business logic so our workflow services are highly testable. We have seen a few examples provided which point to wrapping the Receive activity with a code activity that instantiates an implementation of IReceiveMessageCallback in order to get a reference to the OperationContext. Link to Maurice’s Blog Post. However, this means activities internal to the service are dependent on the existence of the operation context and possibly even the IClaimsIdentity.
The best solution we can come up with so far is to create an implementation of IDispatchMessageInspector for the service that interrogates the token and creates the application user objects needed by the workflow making them available to the workflow runtime via InstanceContext.Extensions. This seems to work but doesn’t feel exactly solid. Any help or feedback is greatly appreciated!
Service Behavior
public class SecurityTokenServiceBehavior : IServiceBehavior, IDispatchMessageInspector
{
...
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
var claimsPrincipal = (IClaimsPrincipal)(Thread.CurrentPrincipal is GenericPrincipal ? null : Thread.CurrentPrincipal);
...
instanceContext.Extensions.Add(new SecurityContextExtension(appUser, audit));
return null;
}
...
}
IReceiveMessageCallback
public class SecurityContextCallback : IReceiveMessageCallback
{
[DataMember]
public SecurityContextExtension SecurityContext { get; private set; }
public void OnReceiveMessage(OperationContext operationContext, ExecutionProperties activityExecutionProperties)
{
SecurityContext = operationContext.InstanceContext.Extensions.Find<SecurityContextExtension>();
}
}
Did you see this blog post about using the
ClaimsAuthorizationManageras well? Using theClaimsAuthorizationManageris the usual way to check for authorization when using WIF.See Dominick post here for some example on how to embed checks in your code using either the
ClaimsAuthorizeattribute or the staticClaimsAuthorize.CheckAccess()method. You might also want to take a look at the WF Security Pack CTP 1 here.