IISExpress 是单线程的吗?

Rub*_*aus 2 c# asp.net httpcontext claims-based-identity

我正在编写一个自定义的 .Net 应用程序,该应用程序利用 Claims 来确保安全性,因为我们跨越了许多边界 - Web、API、批处理等等。在开发过程中,有时我会在通过 Chrome 登录时在系统中创建一些东西,然后我将通过 Edge 中的不同帐户测试新创建的项目,并以某种方式HttpContext.Current.User.Identity对应于我的 Chrome 会话。我确实Thread.CurrentPrincipal在幕后设置,但我的理解一直是所有进入 IIS 的请求都会产生一个新线程,所以我无法弄清楚为什么 Edge 请求被处理为好像它们是 Chrome 请求一样。

是否有可能因为 Visual Studio 处于调试模式而共享此信息?

Eri*_*sch 5

是的,IIS(因此 IISExpress,它是以“应用程序”格式打包的 IIS)是多线程的。但是,您做出了一些不正确的假设。

首先,没有。新请求不会产生新线程,它在线程池线程上运行,并且这些线程池在前一个请求完成后(或者,您将在一分钟内看到,当异步请求等待时)重新使用。

其次,您不应该设置Thread.CurrentPrincipal,因为 IIS 不仅是多线程的,而且是异步的。这意味着如果您的线程等待,当它恢复时,它可能运行在与它启动的线程不同的线程上。

第三,Thread.CurrentPrincipal通常是工作进程(或 AppPool)身份的标识,更改此标识会更改整个线程运行的安全上下文。更好的选择是使用WindowsImpersonationContext该类进行模拟(我假设您正在尝试这样做)。

WindowsIdentity clientId = (WindowsIdentity)User.Identity;

// When 'using' block ends, the thread reverts back to previous Windows identity,
// because under the hood WindowsImpersonationContext.Undo() is called by Dispose()
using (WindowsImpersonationContext wic = clientId.Impersonate())
{
    // do your work that needs the identity
}
Run Code Online (Sandbox Code Playgroud)

如果确实需要设置自定义主体,则通常应使用HttpContext.Current.User而不是 Thread.CurrentPrincipal。