We had implemented a custom authorization method based on the PTWcfServiceAuth example. Everything works fine, except for one big thing. At the end of the process, in a WCF service implementation, we reference the Csla.ApplicationContext.User but it returns an empty object.
We had traced the process and verified that the identity is created and copied into the CSLA.ApplicationContext, (Same as example code of PTWcfServiceAuth.Evaluate method), but it returns an empty object.
Help would be much appreciated.
Remember that WCF treats this as a two-step process: authentication and then authorization. At the end of the authentication process WCF sets the current principal to a WCF-created value, not your value.
Read the Using CSLA .NET 3.0 chapter on how this works for a full discussion, but it is critical that you reset the principal value in the authorization step by providing the principal and identity objects back to WCF's context so WCF can set the thread's principal when it is ready.
Hi Rocky, thanks for you answer.
We followed your advice, but still with no apparent results. I think our problem is at the end of the process call (according to your book, at the service invocation step.) We cannot manage to get the Csla.ApplicationContext.User filled with the resulting principal.
We get the principal name with the ServiceSecurityContext.Current.PrimaryIdentity.Name property. This, make us think that the custom PrincipalPolicy.Evaluate method was succesfully executed, and that at the end of the proccess, it was stored back to WCF context as it should be.
What is not clear (for us) is if it is necessary to call the GetPrincipal(username) method at the beginning of the service implementation to fill the Csla.ApplicationContext.User object again. This question raises by the fact that when the process enters the service implementation, Csla.ApplicationContext.User object is empty again.
Or may be that WCF is executing the call in another trhead?
Thank You in advance.
Hmm, then I don’t know.
WCF may, in fact, run some of that service-call-startup code on another thread. The thread is not guaranteed to be consistent, only the AppDomain is consistent (which is why PrincipalCache stores its values in the AppDomain).
The whole point of setting up the custom authenticator and authorizer components and registering them with WCF is to avoid having to call a GetPrincipal(username) method at the start of every service. I am sure you could successfully make such a call, but it is not an ideal solution in my view.
It is my understanding that, during the authorization phase, you need to pass the new principal and identity objects back to WCF through its context. Then it sets the thread principal on the correct thread before invoking your actual service implementation.
Remember that Csla.ApplicationContext.User is merely a wrapper for Thread.CurrentPrincipal (or HttpContext.Current.User), so the underlying problem is that you aren’t convincing WCF to set the current principal object at the thread/HttpContext level.
You can use remote web server debugging to walk through the code. If you are running the service on your dev box you should be able to put breakpoints in the Evaluate() method to make sure it runs and completes as expected.
Copyright (c) Marimer LLC