如何阅读IdentityServer3上的ASP.NET会话? OWIN管道订单已被破坏

时间:2016-08-07 05:33:28

标签: asp.net owin identityserver3 owin-middleware

问题:我正在尝试在IdentityServer3控制器上使用ASP.NET Session ,但我无法使其正常工作。

我发现这个类似的question解释了如何在OWIN中间件上启用会话,并且它工作得很好:我在IdentityServer之外创建了一些控制器(即,在“/ core”中映射的管道之外)和它工作得很好。我还在我的控制器中添加了Autofac,以确保Autofac(在IdentityServer中使用的扩展)不是问题,并且它工作正常。

这是有效的代码 - Startup.cs:

// register middleware that enables session using SetSessionStateBehavior(SessionStateBehavior.Required)
app.RequireAspNetSession(); 

var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);

var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<DummyClassCreatedByAutofac>();;
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

//app.UseIdentityServer(); // if I add IdentityServer, context.Session is always null

这很好用。中间件(SetSessionStateBehavior)在每个请购单上运行,并且会话在构造函数上可用。但是,只要我将app.UseIdentityServer()添加到我的Startup.cs,IdentityServer就会开始正常工作(并且所有请求都会通过会话中间件)但现在所有控制器的Session都为空 - 不仅对于IdentityServer控制器而且对于我的其他控制器(在IdentityServer管道之外) - 它们停止工作。

如果我完全删除了所有代码并且只是坚持使用常规的IdentityServer管道,那么我只是找不到在管道中添加RequireAspNetSession()的正确位置。我尝试在许多不同的地方添加,但无法使其发挥作用。

经过一些反复试验,我意识到会话中间件RequireAspNetSession()被以下两​​个调用打破:app.UseEmbeddedFileServer()app.ConfigureCookieAuthentication。当两个调用都被删除时,IdentityServer控制器可以使用Session(并且还可以再次访问我的其他控制器)。可能问题是因为其中一些OWIN中间件在特定stages上运行(使用UseStageMarker并定义PipelineStage),并且可能我打破了中间件的优先级顺序。例如,UseEmbeddedFileServer在阶段PipelineStage.MapHandler上运行,以及 RequireAspNetSession。

我尝试在这些中间件之前和之后添加app.RequireAspNetSession(),但它也没有用。事实上,app.RequireAspNetSession()在Map()方法中使用时永远不会起作用,而Map()方法是配置这些中间件的地方(在UseIdentityServer()内):

app.Map("/core", coreApp =>
{
  // this DOESN'T work, even if I remove
  // UseEmbeddedFileServer() or ConfigureCookieAuthentication()
  coreApp.RequireAspNetSession(); 
  //...
  coreApp.UseIdentityServer(idsrvOptions); 
}

_

// this WORKS as long as inside the Map() I don't call 
// UseEmbeddedFileServer() or ConfigureCookieAuthentication() 
app.RequireAspNetSession(); 
app.Map("/core", coreApp =>
{
  //...
  coreApp.UseIdentityServer(idsrvOptions);
}

最后,如果我不使用Map方法(并直接在根文件夹上设置IdentityServer API),它工作正常(会话可供所有控制器使用,即使我保留UseEmbeddedFileServer()和ConfigureCookieAuthentication()中间件)。但这是不可接受的,因为我需要在映射文件夹上运行API。

总结:如果我在Map()中使用RequireAspNetSession(),它就不起作用(session始终为null)。如果我在Map()之外使用RequireAspNetSession()但在Map()中保留UseEmbeddedFileServer()或ConfigureCookieAuthentication(),它也不起作用。

如何使RequireAspNetSession()在IdentityServer3管道中工作?

另外,Map(“/ core”)如何影响(并破坏)我在该管道之外托管的DefaultController的管道?

1 个答案:

答案 0 :(得分:0)

它没有破碎。这是设计的。 IdentityServer故意清除会话。

你有几种选择。

1)你可以创建一个cookie助手
2)SignInMessage可以满足您的大部分需求 - &gt;别忘了LoginViewModel

您的用户或应用程序登录后,会话再次由您控制。