HttpContext.Current.Session为null + OWIN

Aur*_*tal 10 asp.net authentication session owin

我是OWIN的新手,这个问题一直是我的主要障碍.

基本上,在我的MVC应用程序中,我在Startup类中有以下内容:

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
                        }
                    }
                });
Run Code Online (Sandbox Code Playgroud)

我不明白为什么我在调试Session时为null.HttpContext.Current属性不是.Sessions + OWIN有任何限制吗?这个问题有解决方法吗?应该如何接近它?

旁注1:我试图添加我在其中一个SO问题中找到的这段代码,而Session仍然是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();
            });
Run Code Online (Sandbox Code Playgroud)

旁注2:我似乎不再找到它,但有人建议在其中一个SO问题中在Global.asax中添加空方法Session_Start和Session_End(作为空方法).这既不起作用.

我欢迎任何建议.谢谢!

小智 11

你快到.您的会话仍然为空的原因是您没有指示OWIN在您的中间件执行之前初始化System.Web Sessions.

通过中间件注册添加.UseStageMarker(..) ,您将告诉OWIN它在执行pipline中应该执行哪些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);
Run Code Online (Sandbox Code Playgroud)

默认情况下,Owin Middleware在最后一个事件(PipelineStage.PreHandlerExecute)上运行,在这种情况下对你来说太迟了.

现在,要使用会话,您需要使用第二个中间件,该中间件在Asp.Net运行时获取会话之后运行.必须在PostAquireState阶段运行此中间件,如下所示:

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

     return next();
})
.UseStageMarker(PipelineStage.PostAcquireState);
Run Code Online (Sandbox Code Playgroud)

Asp.Net katana docs有一篇关于中间件如何工作的优秀文章.有关Asp.net中执行顺序的详细信息,请参阅PiplineStage枚举文档和HttpApplication文档.