IISExpress是单线程的吗?

时间:2017-04-13 02:56:10

标签: c# asp.net claims-based-identity httpcontext

我正在编写一个自定义.Net应用程序,该应用程序利用声明来保护安全,因为我们跨越了许多界限 - 网络,API,批处理等等。在开发过程中,我会在通过Chrome登录时在系统中创建内容,然后我将通过Edge中的其他帐户测试新创建的项目,并且HttpContext.Current.User.Identity对应我的Chrome会话。我在幕后设置Thread.CurrentPrincipal,但我的理解一直是所有进入IIS的请求都会产生一个新线程,所以我无法弄清楚边缘请求被处理的原因就像它们是Chrome请求一样。

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

1 个答案:

答案 0 :(得分:4)

是的,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
}

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