Session state is not available in this context - AcquireRequestState in Global.asax

Session state is not available in this context - AcquireRequestState in Global.asax

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


tarekahf posted on Sunday, September 11, 2011

Since implemetning CSLA .NET for VS 2005, I was getting occasional problems in "Application_AcquireRequestState" in Global.asax. The causes were due server session lost before the Forms Authentication Ticket has expired. This causes the application to be logged-in from the client, but not logged in on the server. Actually, such cases were conflicting in other parts inside my application, where some ASPX pages are protected, and others are not protected. In some pages, authentication need to take place inside the page, in order to avoid redirection, and to avoid loosing the "Request.InputStream".

Also, in some cases, I was getting this error inside "Application_AcquireRequestState":

Session state is not available in this context
Error Code: -2147467259

I found out later the code was update in CSLA .NET for VS 2008. I used it, and I found that such problems have been resolved. Eventually I had to udpate the code to be as follows in order to make it work for all cases:

    Protected Sub Application_AcquireRequestState( _
      ByVal sender As Object, ByVal e As System.EventArgs)
        Dim DoSkip As Boolean = False
        Dim theAnnonymousPrincipal As System.Security.Principal.GenericPrincipal = Nothing
        Dim theUrlAccessForAnnonymousPrincipal As Boolean = False
  
        Dim principal As System.Security.Principal.IPrincipal = nothing
        Try
            principal = _
              CType(Session("CslaPrincipal"), System.Security.Principal.IPrincipal)
        catch ex as System.Web.HttpException
            if ex.ErrorCode = -2147467259 then
                DoSkip = True
            end if
        Catch ex as Exception
            principal = Nothing
        End Try
        If Not DoSkip Then
            If principal Is Nothing Then
                theAnnonymousPrincipal = New System.Security.Principal.GenericPrincipal(New System.Security.Principal.GenericIdentity(""), Nothing)
                theUrlAccessForAnnonymousPrincipal = UrlAuthorizationModule.CheckUrlAccessForPrincipal(Request.Url.LocalPath, theAnnonymousPrincipal, "POST")
                ' if the requested page is public, then no need to re-authenticate.
                If Not theUrlAccessForAnnonymousPrincipal Then
                    If User.Identity.IsAuthenticated AndAlso _
                        TypeOf User.Identity Is FormsIdentity Then
                        FormsAuthentication.SignOut()
                        Response.Redirect(Request.Url.PathAndQuery)
                    End If
                    ' didn't get a principal from Session, so
                    ' set it to an unauthenticted PTPrincipal
                    CSLAIDB.Library.Security.IDBPrincipal.Logout()
                End If
            Else
                ' use the principal from Session
                Csla.ApplicationContext.User = principal
            End If
        End If
    End Sub

The above code has solved the following problems (after testing it for a few days):

1. When the Server Session has expired, and need to re-authenticate inside a public page.

2. Need to maintain the Submitted stream using "Reques.InputStream"

3. Avoid occasional error "Session state is not available in this contect".

I posted this in case someone else find it useful.

Tarek.

tarekahf replied on Monday, October 10, 2011

Just to confirm that the above code is working very well since it was deployed live.

Also, I want to add that you need to make sure that the TimeOut Period of the authentication Cokie is longer than the TimeOut of the Server Side Session.

Hope this will be helpful to others.

Tarek.

Copyright (c) Marimer LLC