Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpContext.Current.Session is null + OWIN

I'm entirely new to OWIN and this issue has been a major blocker for me.

Basically, at my MVC app I have the following at Startup class:

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = OfficeSettings.ClientId,
                    Authority = OfficeSettings.Authority,

                    TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters()
                    {
                        RoleClaimType = "roles"
                    },

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {

                    AuthorizationCodeReceived = (context) =>
                        {
                        // code hidden for readability

                            if(HttpContext.Current.Session == null)
                            {
                                // It's null. Why is that?
                            }

                            var session = HttpContext.Current.Session;
                            if (session["myMockSession"] != null)
                            {
                                // Do stuff...
                            }
                        },

                        RedirectToIdentityProvider = (context) =>
                        {
                            // code hidden for readability
                        },

                        AuthenticationFailed = (context) =>
                        {
                            // code hidden for readability
                        }
                    }
                });

I don't understand why when I'm debugging that the Session is null. HttpContext.Current Property isn't. Are there any constraints with Sessions + OWIN? Is there any workaround for this issue? How should one approach it?

Side note 1: I've tried to add this piece of code I've found in one of the SO questions and the Session was still null:

app.Use((context, next) =>
            {
                // Depending on the handler the request gets mapped to, session might not be enabled. Force it on.
                HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
                httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
                return next();
            });

Side note 2: I don't seem to find it anymore, but someone suggested in one of the SO questions to add empty methods Session_Start and Session_End (as empty methods) at the Global.asax. That didn't worked neither.

I'm welcoming any advises. Thanks!

like image 455
AuroMetal Avatar asked Jun 20 '16 11:06

AuroMetal


People also ask

Why HttpContext current is null?

It won't work in the scheduling related class because relevant code is not executed on a valid thread, but a background thread, which has no HTTP context associated with. Overall, don't use Application["Setting"] to store global stuffs, as they are not global as you discovered.

What is use of HttpContext current session?

HttpContext. Current. Session simply returns null if there is no session available. The HttpApplication's implementation of the Session property throws an HttpException with the message Session state is not available in this context.

How do I clear HttpContext current session value?

Session. Clear() just removes all values (content) from the Object. The session with the same key is still alive.

What is the difference between session and HttpContext current session?

There is no difference. The getter for Page. Session returns the context session.


1 Answers

You're almost there. The reason your session is still null is that you have not instructed OWIN to initialize System.Web Sessions prior to your middleware is beeing executed.

By adding .UseStageMarker(..) after your middleware registration you'll tell OWIN where in the execution pipline it should perform SetSessionStateBehaviour

app.Use((context, next) =>
{
    var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
    httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
    return next();
});

// To make sure the above `Use` is in the correct position:
app.UseStageMarker(PipelineStage.MapHandler);

By default, Owin Middleware run at the last event (PipelineStage.PreHandlerExecute) which is too late for you in this case.

Now, to use sessions, you need to work in a second middleware, that runs after the session has been Aquired by the Asp.Net runtime. This middleware must be run in the PostAquireState phase, like so:

.Use((context, next) =>
 {
     // now use the session
     HttpContext.Current.Session["test"] = 1;

     return next();
})
.UseStageMarker(PipelineStage.PostAcquireState);

Asp.Net katana docs has an excellent article on how the middleware works. See the PiplineStage enum docs and the HttpApplication docs for details on the execution order in Asp.net.

like image 102
Johan O Avatar answered Sep 22 '22 20:09

Johan O