Storing Principal in Cookie...

Storing Principal in Cookie...

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


ballistic posted on Friday, October 17, 2008

I would like a user to login and have their Principal/Identity stored in a cookie.

I have been able to use a Session and get this working.

System.Web.HttpContext.Current.Session("CommunityPrincipal") = Csla.ApplicationContext.User

Global.asax:
Protected Sub Application_AcquireRequestState(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim Principal As System.Security.Principal.IPrincipal
        Try
            Principal = CType(Session("CommunityPrincipal"), System.Security.Principal.IPrincipal)
        Catch
            Principal = Nothing
        End Try
   
        If (Principal Is Nothing) Then
            ' Didn't get a principal from Session, so set it to an unauthenticted CommunityPrincipal
            Community.Library.Security.CommunityPrincipal.Logout()
        Else
            ' Use the principal from Session
            Csla.ApplicationContext.User = Principal
        End If
    End Sub

However, since the requests to the server will be load balanced on each request, I cannot use Session since I cannot guarantee that the user will be on the same server each time.

I figured all I had to do was serialize my Principal object and store that into a cookie instead of Session, but I get a problem saying it is not able to Serialize the Principal object.

Not really sure how I would go about making my Principal object serializable.

JoeFallon1 replied on Sunday, October 19, 2008

Your original code seems fine.

The idea about putting it in to a cookie is not a good choice though. Do not do it.

To make your Principal serializable just add the Serializable attribute to the top of your Class declaration.

You have two good ways to stroe your session data out of process. In fact you should probably not have ever used In-Proc session state in a production app because the AppDomain recycles frequently and you lose all your session data. You should have been using an Out of Process State Server instead.

For a single Web Server the State Server could even be the same physical box! What it does is serialize the Session state to a separate process (which you start from Services - it is called ASP.Net State Server Service - or something like that.)

When you need to scale out and add a Web farm you can add a separate box loaded with RAM and then point each of the Web Servers at it as the State Server for the entire web farm. Then the data is serialized over the network to the out of proc State Server. This way there is no need for sticky sessions and any web server can serve any request because they all share the same session state.

The only "trick" is that all of the web servers in the farm must use the same machine key in their config files. You can Google this to find out the best way to create a key and set the value for all the servers in the farm to the same thing.

You can also use a SQL Server database as a State Server. A key concept here is that it can be a totally different box and DB than the one used for your app! The only purpose of this SQL Server is to store Session state in a blob for later retrieval. There are lots of articles on how to set it up and configure it - I think MS provides you with a script someplace.

It might even be possible now to use a different DB server (like Oracle) for this - originally it was SQL Server only - not sure if others support tihs now. Depends on if you need Oracle or something.

The 2 out of process options are about the same speed as each other. And both are about 50% slower than In-Proc sessions. You pay a penalty for serializing data over the wire. But you gain scalability and stability so it is worth it.

Joe

 

 

 

Copyright (c) Marimer LLC