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