Can different CSLA-based applications overwrite each other's principal?

Can different CSLA-based applications overwrite each other's principal?

Old forum URL: forums.lhotka.net/forums/t/7783.aspx


xxxJasonxxx posted on Wednesday, October 14, 2009

Can different CSLA-based applications overwrite each other's principal?

(note: we're using CSLA version 3.0.4.0)

This is why I'm asking...

In my custom principal object's Login method I have this code that stores the principal into some globally available CSLA area:

Csla.ApplicationContext.User = principal

Then in the factory methods of my various business objects, I have this code that checks that principal we stored earlier to make sure the user is actually authenticated:

If Csla.ApplicationContext.User.Identity.IsAuthenticated = False Then
Throw New System.Security.SecurityException(My.Resources.UserNotLoggedInException)
End If

Now say I have a couple different applications using a couple different CSLA-based assemblies running on the same machine. Are they going to overrwrite each other's principal? If so, did I misunderstand CSLA security and should I be handling this differently somehow?

Thanks,

Jason

ajj3085 replied on Wednesday, October 14, 2009

It should be storing the principal with either the thread, or if you're running under asp.net, in the HttpContext, or if you're running in Wpf on the Application.

So it depends on what UI you're using to some extent, but I would be suprised if this happened, since HttpContext, Thread and System.Windows.Application are all distinct within a process.

xxxJasonxxx replied on Wednesday, October 14, 2009

My concern is that I foresee a situation coming down the road where we will have multiple CSLA-based applications/assemblies running on the SAME THREAD and using DIFFERENT LOGINS. And I'm thinking the logins/principals will overwrite each other (I'm working on a test of this right now).

So I'm toying with the idea of changing my Login method so that it does NOT store the principal in CSLA.Application context. And instead changing the Login method to return the principal object to the caller of the Login method (to be saved by the caller and later provided as needed). Then I'd add a Principal parameter to the factory method of each business object and let each business object store it's own principal object internally in a global variable. Then each business object's internal authentication and authorization checks would look at the principal in the global variable instead of the principal in CSLA.Application context.

Does this sound crazy...or am I missing some critical point of understanding?

JonnyBee replied on Wednesday, October 14, 2009

Hi,

No, that scenario will not work. You cannot have multiple versions of Csla (assembly) running on the same tread, because same class in same namespace defined more than one time in loaded assemblies will make .Net runtime throw an Exception.  You can have several business assemblies but they must all use the same version of Csla.dll to run in the same application (or thread).

And I cannot predict a logical usage of more than one Principoal object for a thread (=> eg. AuthorizationRules in Csla alwas loook at Csla.ApplicationContext.User)

xxxJasonxxx replied on Wednesday, October 14, 2009

Finished the test.....two different CSLA-based assemblies(DLLs), with different logins, being accessed in the SAME thread (a single Windows Form). They DID overwrite each other's principal, stored in CSLA.ApplicationContext.

Also tested.....two different CSLA-based assemblies(DLLs), with different logins, being accessed in DIFFERENT threads (two separate Windows Forms apps). They did NOT overwrite each other's principal, stored in CSLA.ApplicationContext.

JonnyBee replied on Wednesday, October 14, 2009

Hi,

Yes, in the first example both CSLA based assemblies must reference the same version of CSLA.

If you also assume that these assemblies come from different sources they may also be published using different versions of CSLA and then you will really get into trouble.

RockfordLhotka replied on Wednesday, October 14, 2009

The .NET framework (this is not a CSLA thing) stores the user's principal on the thread.

In the ASP.NET environment, ASP.NET takes care to reset the principal (or allow you to do so) on each page request so threads can be reused.

Windows Forms has no such pre-built plumbing. Which is not to say that you can't implement such plumbing yourself.

If you make the .NET principal (System.Threading.Thread.CurrentPrincipal) correct with your own plumbing, then Csla.ApplicationContext.User will also be correct, since it just provides you with the .NET principal.

If you go down that road, you should consider that Csla.ApplicationContext stores local, client and global context values on the thread as well. So you'd probably want to manage those as well.

xxxJasonxxx replied on Thursday, October 15, 2009

Rocky,

Thanks for mentioning that:
"If you go down that road, you should consider that Csla.ApplicationContext stores local, client and global context values on the thread as well. So you'd probably want to manage those as well."

I'd forgotten that the context not only stores the "Principal" I was worried about, but also "GlobalContext", "ClientContext", "IsRemotePortal", "ClientCulture", and "ClientUICulture". And I'm honestly not experienced/knowledgable enough to figure out a way to deal with all of that - maybe just the Principal - but not the other stuff.

So now I'm wondering if I should focus my efforts on a way to make sure our different CSLA objects/DLLs (that have different login implementations) will always run on separate threads even when they are used together in the same Web or Windows application. Maybe in those scenarios I could create some type of separation/integration point with WCF......

Jason

ajj3085 replied on Friday, October 16, 2009

Even if you could do that, under asp.net I'm not sure how you'd ensure that each assembly runs under a different HttpContext. I'm not even sure that would work if you could.

This almost sounds to me like you're combinin multiple applications into one... if that's the case, then they should all share the same security model. If you really have seperate applications and need to maintain that, then the applications need a way to talk to each other, not directly though but with intermediate assemblies or possiblly something like web services (or some other similar API).

Just something to think about.

Copyright (c) Marimer LLC