2017-04-13 74 views
1

我正在编写一个自定义的.Net应用程序,该应用程序利用声明来实现安全性,因为我们跨越了许多界限 - Web,API,批处理等等。在开发过程中,有些时候我会通过Chrome登录后在系统中创建一些内容,然后我将通过Edge中的其他帐户去测试新创建的项目,并以某种方式HttpContext.Current.User.Identity对应于我的Chrome会话。我在后台设置了Thread.CurrentPrincipal,但我的理解一直是,所有到IIS的请求都会产生一个新线程,所以我无法弄清楚为什么Edge请求正在处理,就好像它们是Chrome请求一样。是IISExpress单线程?

是否有可能因为Visual Studio是在调试模式下,它的分享这些信息?

+0

_“......要求到IIS中创建新的线程...” _ - 最有可能的请求会在下一可用线程池线程。所以线程ID随着时间的推移将不会是唯一的 – MickyD

+0

@rubyhaus实际上你的担心是什么,我假设什么时候在chrome中有同一用户的请求,你不想让他在其他浏览器中,这是你正在尝试实现 ? – Webruster

回答

4

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

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

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

第三,Thread.CurrentPrincipal通常是工作进程(或程序池)的身份的身份,改变这改变了整个线程下运行的安全上下文。一个更好的选择是使用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中自定义主体。

+0

我在网页设置了'HttpContext.Current.User',但是没有在任何地方引用'System.Web',我该如何让底层库(主要是业务层)知道经过身份验证的用户是谁?我试图避免引用System.Web,因为并非所有东西都会使用Web组件。我一直认为来自Microsoft的Membership API来设置ThreadPrincipal,因此走这条路。 – RubyHaus

+1

@RubyHaus - 是的,微软的代码往往做了很多的事情,我们,我们一般不应该,因为MS知道它在做什么,并妥善处理清理和边缘的情况下,我们往往不知道有足够的了解的内部,它通常是最好避免它们。你在做某种自定义身份验证吗?你能否简单地将信息从网络层传递给图书馆? –

+0

我希望有一个更加无缝的方式去做,但我可以想出办法做到这一点。谢谢您的帮助! – RubyHaus