http.context.user和thread.currentprincipal的区别以及何时使用它们?

21

最近我在Visual Studio 2008下运行ASP.NET Web应用程序时遇到了一个问题。错误提示为“类型未解析为成员...customUserPrincipal”。在追踪各种讨论组之后,似乎发现当你将自定义原则分配给Thread.CurrentPrincipal时,Visual Studio的Web服务器存在问题。

在我的代码中,我现在使用...

HttpContext.Current.User = myCustomPrincipal
//Thread.CurrentPrincipal = myCustomPrincipal

很高兴我解决了这个错误,但是这引出了一个问题:“这两种设置principal的方法有什么区别?”虽然有其他与此相关的stackoverflow问题,但它们没有详细介绍这两种方法的区别。

我发现有一篇诱人的帖子,其中包含以下夸张的评论,但没有解释来支持他的说法...

在所有的web(ASPX/ASMX)应用程序中使用HttpConext.Current.User。

在所有其他应用程序中,如winForms、控制台和Windows服务应用程序中,使用Thread.CurrentPrincipal。

您们任何安全/dot.net专家能否解释一下这个主题呢?

3个回答

27
当HttpApplication对象获取一个线程时,它首先要做的事情是将该线程的principal设置为HttpContext的principal。这样可以同步principals。
但是,如果您稍后去设置Thread的principal,HttpApplication在用户上下文中仍然有不同的principal设置。这就是为什么您应该始终通过HttpContext进行设置的原因。
(如果你用Reflector看一下,你会看到当你在HttpContext.User上进行“设置”时运行的复杂代码——它使用IIS进行了大量内部处理来正确地设置principal。)

2
对于阅读此内容的任何人,只是一个提示:即使您稍后设置了HttpContext.User,似乎也不会将其复制到Thread.CurrentPrincipal。至少在我们的消息处理程序中是这样的。我们必须同时设置两者。 - O'Rooney

8
在webforms应用程序下,我认为Thread.CurrentPrincipal将是运行工作进程(线程)的用户主体。 HttpContext.Current.User将是当前已登录的Web用户。
在表单/WPF应用程序中,这种情况是合理的,因为您感兴趣的是正在运行应用程序的用户。
您是想伪装工作进程还是已登录的用户?

1
根据我在本地使用IIS 7.5 .NET 4.5进行的测试,这个答案是错误的,@womp的答案是正确的。默认情况下,Thread.CurrentPrincipal和HttpContext.Current.User都返回应用程序/ Web用户。System.Security.Principal.WindowsIdentity.GetCurrent()和Environment.UserDomainName + Environment.UserName都返回IIS应用程序池/工作进程标识。 - BateTech
1
我想知道自从4.5年前写下这个答案以来是否有所改变,如果是的话,也许@yamspog可以重新将其他答案标记为被接受的答案。 - Aren

6
这篇文章能解释清楚吗?以下是摘录内容:

http://www.hanselman.com/blog/CommentView.aspx?guid=22c42b73-4004-40ce-8af9-47f1b9b434ed

I have some code in an ASP.NET custom FormsAuthentication Login that looks something like this:

// This principal will flow throughout the request.
VoyagerPrincipal principal = new VoyagerPrincipal(yada, yada, yada);

// Attach the new principal object to the current HttpContext object
HttpContext.Current.User = principal;

It is called on the Global.asax's AuthenticateRequest so everything is all setup before the Page's events fire. It provides a custom IPrincipal that integrates our eFinance Server with ASP.NET. It's quite a lovely subsystem, IMHO.

Other operations count on being able to get this 'Call Context' IPrincipal from the current thread at any time. In another section of code someone was doing this in the MIDDLE of the HttpRequest (somewhere in the Page_Load) after having JUST called the routine above for the first time:

return Thread.CurrentPrincipal as VoyagerPrincipal;

In the instance where someone calls the first chunk of code then expects to be able to call the second chunk within the same HttpRequest, the Thread.CurrentPrincipal contains a GenericPrincipal populated much earlier by the HttpApplication. (Or a WindowsPrincipal, depending on your settings).


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接