Hi everyone.
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.
Possible causes?
Help would be much appreciated.
Thank You
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.
Rocky
Copyright (c) Marimer LLC