I've upgraded WebForms project to use Csla 4. The business layer seems fine mostly, all the tests have passed and I'm fixing minor things with how BOs are build (private backing fields not specifying that in relationship type, etc).
One thing I'm stumped on is the handling of the ApplicationContext.User. I'm setting it in each request, but it seems that by the type code runs which interacts with a BO its been reset back. I have this block of code. Initially, the user is GenericPrincpal wrapping a CslaIdentity. I use that to pull the real principal and set it as shown, but I get a SecurityException when trying to modify a property value and its back to GenericPrincipal.
Any ideas? This all worked fine on Csla 3.8.3.
protected void Application_AuthenticateRequest( object sender, EventArgs e ) {
string userName;
var formAuthCookie = HttpContext.Current.Request.Cookies[ FormsAuthentication.FormsCookieName ];
var isAuthenticated = HttpContext.Current.Request.IsAuthenticated;
if ( isAuthenticated || formAuthCookie != null ) {
if ( !isAuthenticated ) {
var ticket = FormsAuthentication.Decrypt( formAuthCookie.Value );
userName = ticket.Name;
}
else {
userName = HttpContext.Current.User.Identity.Name;
}
var prin = (IPrincipal)HttpContext.Current.Cache[ userName ];
if ( prin != null ) {
Csla.ApplicationContext.User = prin;
}
}
}
Which version of Csla are you using?
You should make sure to have csla.web.dll in your bin folder
Are you using BackgroundWorkers in your web application?
BackgroundWorkers will not have accesss to HttpContext and CSLA will switch to use Csla.ApplicationContextManager and get the principal object from the Thread.CurrentThread.
When Csla.Web.dll exists in bin folder Csla.Web.ApplicationContextManager is loaded and used for ApplicationContext
/// <summary> /// Gets the current principal. /// </summary> public System.Security.Principal.IPrincipal GetUser() { return HttpContext.Current.User; } /// <summary> /// Sets the current principal. /// </summary> /// <param name="principal">Principal object.</param> public void SetUser(System.Security.Principal.IPrincipal principal) { HttpContext.Current.User = principal; }
Csla 4.1, and Csla.Web is in the bin folder or the CslaDataSource wouldn't work. No background workers, this is all in the request thread.
Any other ideas on this?
If you put a breakpoint in your page load event, is the principal set at that point?
How about at the end of your method in global.asax?
The only way to solve this, I think, is to figure out exactly when the principal is cleared, and then try to figure out how/why that occurs.
No, the principal is gone by the time the page load event fires (rather reset to the forms one). It IS set after the event I posted. Is there another application event I should look at? I'll try dropping the pdbs in the bin and seeing if I can't put a breakpoint in the ApplictionContext.User setter.
Copyright (c) Marimer LLC