Some interesting findings when trying to get ASP Forms Authentication to play with CslaLight WCF

Some interesting findings when trying to get ASP Forms Authentication to play with CslaLight WCF

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


paupdb posted on Thursday, August 14, 2008

I've had some fun whilst working on the above topic.

Basically I have an existing ASP.Net Forms authentication setup that I wanted to integrate with a Silverlight application which uses CslaLight + CSLA3.6.

I set the WcfPortal service to run with ASPNetCompatibility mode (was relieved to see the ASPNetCompatibility attribute on the WcfPortal class btw), and then attempted to access HttpContext.Current.User from within one of my BOs on the server.

What was interesting was that I kept getting a Csla.Security.UnauthenticatedPrincipal back when debugging the HttpContext.Current.User - clearly not my FormsIdentity.

After trying a whole bunch of different configuration options in the ServiceReferences.clientconfig and the web.config, I then stumbled upon some of the code in the DataPortal client implementation where a ApplicationContext.User is serialised automatically in the BeginFetch routines.
I realised that every call to the WcfPortal would send the ApplicationContext.User too, and when there isnt a ApplicationContext.User set, then a blank one (UnauthenticatedPrincipal) is sent.

Now this causes me a problem, because I am relying on the server to initially provide the SL client back with an authenticated principal following a "start-up" BO call through the DataPortal (the server code would access the Forms authenticated principal and then load a CSLA principal for that Forms authed user), rather than the usual case of the SL client providing the server with their username and password through a login screen in the SL app.
After getting back the CSLA principal once, then that would be kept in the SL client and I would use that principal going forward.

The CSLA client behaviour isnt necessarily an issue on its own, however when combined with the fact that on the server side the ApplicationContext.User is set to the deserialised one just received over the wire, then I immediately saw my issue.
This is because in Csla.ApplicationContext, the following code exists:
    public static IPrincipal User
    {
      get
      {
        if (HttpContext.Current == null)
          return Thread.CurrentPrincipal;
        else
          return HttpContext.Current.User;
      }
      set
      {
        if (HttpContext.Current != null)
          HttpContext.Current.User = value;

        Thread.CurrentPrincipal = value;
      }
    }

So yeah, because a ApplicationContext.User is always sent over the wire from the SL client to the server, I lose my FormsIdentity.
Now I know this CSLA behaviour is by design, so I'm not looking for a framework change.

I have found a way around this by using a custom IAuthorizationPolicy with the WcfPortal service, using this excellent blog post as my guide.  By creating a HttpContextIdentityPolicy of my own, I am able to intercept the HttpContext.Current before CSLA gets its hands on it, and thus the policy is able to copy the HttpContext.Current.User into ServiceSecurityContext.Current.PrimaryIdentity.

I can then access my Forms authenticated user through ServiceSecurityContext.Current.PrimaryIdentity in my BO :)

Whew!

Anyway this is just for people's interest and maybe someone has found a better way to do this?

Also Rocky, you may want to be aware of this admittedly small side effect of having the CSLALight client serialise a blank ApplicationContext.User when one has not been explicitly set by the UI code.

JoeFallon1 replied on Friday, August 15, 2008

Nice post.

I can see myself running in to this issue next year! At which time I will have forgotten about this! Hopefully a Search will bring it back up though.

Joe

paupdb replied on Sunday, August 17, 2008

Thanks Joe.

While researching my approach I came across some of your posts and the login setup you run is very similar to mine.  So I'm sure we can help each other out from time to time.

Copyright (c) Marimer LLC