使用会话存储进行Cookie身份验证的MVC 4 OWIN应用程序导致Thread.CurrentPrincipal!= HttpContext.User

时间:2016-03-31 14:29:28

标签: c# asp.net-mvc asp.net-identity owin wif

在OWIN MVC应用程序中,我试图在请求之间保留BootstrapContext.SecurityToken以允许为联合创建ActAs令牌。

默认情况下,Cookie序列化会尝试保留BootstrapContext.Token(字符串形式)并忽略BootstrapContext.SecurityToken(已解码的令牌),这种情况有意义,避免了解码令牌的曝光?

因此我尝试使用CookieAuthenticationOptions.SessionStore来保留整个BootstrapContext服务器端。这种(有点)有效,但问题如下所述!

背景:

我已经从Katana源代码库[http://katanaproject.codeplex.com/]中的沙箱代码中解除了AspNetAuthSessionStore实现,该代码按预期运行,将票证保存并恢复到HttpContext.Session。

我还解除了以下扩展代码:

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;
    }

    public static IAppBuilder UseAspNetAuthSession(this IAppBuilder app) {
        return app.UseAspNetAuthSession(new CookieAuthenticationOptions());
    }

    public static IAppBuilder UseAspNetAuthSession(this IAppBuilder app, CookieAuthenticationOptions options) {
        app.RequireAspNetSession();
        options.SessionStore = new AspNetAuthSessionStore();
        app.UseCookieAuthentication(options, PipelineStage.PreHandlerExecute);
        return app;
    }
} 

并使用我的OWIN Startup中的注册功能。

问题:

在我的MVC 4目标操作中,我检查以下内容:

 var ctxtuser = HttpContext.User as ClaimsPrincipal;
 var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;

使用直接cookie实现(没有会话存储):

app.UseCookieAuthentication(new CookieAuthenticationOptions() {});

两个主体是相同的并且是期望值(但没有BootstrapContext内容!)。

如果我只是尝试将Session存储添加到此实现中:

app.UseCookieAuthentication(new CookieAuthenticationOptions() {
    SessionStore = new AspNetAuthSessionStore()
 });

由于没有会话存储而失败!大概是因为我们不允许在Authenticate阶段进行会话。

如果我使用上述扩展程序中的注册:

app.UseAspNetAuthSession(new CookieAuthenticationOptions() {
 });

版本然后代码几乎按预期运行,除了Thread.CurrentPrincipal在它命中我的动作时不等于HttpContext.User。上下文用户是我的声明原则,但Thread.CurrentPrincipal设置为匿名的WindowsPrincipal。

我已经通过代码进行了调试,声明主体正在应用于线程和上下文:

 Microsoft.Owin.Host.SystemWeb.OwinCallContext.SetServerUser

但不知何故,Thread版本在点击我的动作之前会被设置回匿名Windows用户?

我认为这与

中的特定管道阶段设置有关
app.UseCookieAuthentication(options, PipelineStage.PreHandlerExecute);

与我请求时使用的默认值(PipelineStage.Authenticate)相反

app.UseCookieAuthentication(new CookieAuthenticationOptions()...

我想知道在Authenticate阶段设置主体的默认代码是否会使它“粘贴”。正如ASP.Net想要使用的那样,等到PreHandlerExecute为时已晚?

但是看不出如何解决这个问题。

我做错了什么?

0 个答案:

没有答案