问题:我正在尝试在 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 的管道?