How to store session data using Owin hosting?

3.5k views Asked by At

I have problem with creating a session in application hosted using Owin. I have tried using RedisSession, but I didn't know how to configure it so it gave me an error. I was looking for a solution for some time, tried different things and finally decided to ask here for help.

Scenario:

  • I'm logging in the application using HTTP POST request,
  • User login and password should be stored in session,
  • For each next GET/POST request which need previous login session is empty (login and password are null).

Object HTTPContext is empty.

I'm using Ninject for dependency injections.

I tried something like that: Can OWIN middleware use the http session?

Does anybody have an idea how to store login data in Owin session?

Below is Owin configuration file, included in it things are from link posted above.

[assembly: OwinStartup(typeof(Service.Startup))]
namespace Service
{
public class Startup
    {
        public void Configuration(IAppBuilder appBuilder)
        {
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }
                );
            appBuilder.RequireAspNetSession();
            appBuilder.UseNinjectMiddleware(CreateKernel).UseNinjectWebApi(config);

        }

        public static StandardKernel CreateKernel()
        {
            var kernel = new StandardKernel(new Module());
            return kernel;
        }
    }
    public static class AspNetSessionExtensions
    {
        public static IAppBuilder RequireAspNetSession(this IAppBuilder app)
        {
            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();
            });
            // SetSessionStateBehavior must be called before AcquireState
            app.UseStageMarker(PipelineStage.MapHandler);
            return app;
        }
    }
}
2

There are 2 answers

0
Mark Good On

For anyone wanting to do this with ASP.net Framework, instead of Core, read on.

First, make sure Owin.Extensions is installed.

Next, add this code to your Owin Startup.cs before the middleware that you want to use session.

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

By default, OWIN Middleware run at the last event (PipelineStage.PreHandlerExecute) which is too late for accessing session state.

.UseStageMarker tells OWIN where in the execution pipeline to execute the function passed to .Use().

To use sessions, you need to execute middleware that runs after the session has been initialized by the ASP.net runtime. This middleware must be run in the PostAquireState phase, like so:

.Use((context, next) =>
 {
     HttpContext.Current.Session["mykey"] = "myvalue";

     return next();
}).UseStageMarker(PipelineStage.PostAcquireState);
0
Anatolyevich On

I've had some struggling with sessions as well.

Here is the solution, which works for me:

1) Add NuGet Microsoft.AspNetCore.Session

2) Call .AddSession on your IServiceCollection. Note, it might need configuration. In my case it is: enter image description here

3) Use your session. Keep in mind, that if there are no values set to a session, on each request SessionID is different. So you'd have to add some value to a session. This is how it would stay the same across multiple requests.

And here is my session pinning middleware: enter image description here

Hope it helps.