0

问题:我正在尝试在 IdentityServer3 Controllers 上使用 ASP.NET Session,但我无法让它工作。

我发现这个类似的问题解释了如何在 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. 当两个调用都被删除时,Session 对 IdentityServer 控制器可用(并且我的其他控制器也可以再次使用)。问题可能是因为其中一些 OWIN 中间件在特定阶段运行(使用UseStageMarker和定义 a PipelineStage),并且可能我打破了中间件的优先级顺序。UseEmbeddedFileServer 例如在舞台上运行PipelineStage.MapHandler,以及 RequireAspNetSession。

我尝试app.RequireAspNetSession()在这些中间件之前和之后添加,但它也不起作用。事实上,app.RequireAspNetSession()在 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(),它就不起作用(会话始终为空)。如果我在 Map() 之外使用 RequireAspNetSession(),但在 Map() 中保留 UseEmbeddedFileServer() 或 ConfigureCookieAuthentication(),它也不起作用。

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

此外, Map("/core") 如何影响(并破坏)托管在该管道之外的 DefaultController 的管道?

4

1 回答 1

0

它没有坏。这是设计使然。IdentityServer 故意清除会话。

你有几个选择。

1)您可以创建一个 cookie 助手
2)SignInMessage 包含您需要的大部分内容 -> 不要忘记 LoginViewModel

一旦您的用户或应用程序登录,会话将再次在您的控制之下。

于 2016-08-09T12:30:07.803 回答