线程可以作为另一个用户执行吗? (.NET 2.0/3.5)
Posted
技术标签:
【中文标题】线程可以作为另一个用户执行吗? (.NET 2.0/3.5)【英文标题】:Can a Thread be executed as another user? (.NET 2.0/3.5) 【发布时间】:2009-04-08 14:12:39 【问题描述】:我有一个 C# 应用程序,它将包含计算的源文件执行一些运行时编译到动态程序集中。显然,这会带来严重的安全问题。
根据以下“公式”,将生成以下代码,并创建一个动态程序集:
公式:
Int32 _index = value.LastIndexOf('.');
String _retVal = value.Substring(_index + 1);
return _retVal;
生成的代码:
using System;
namespace Dynamics
public class Evaluator
public Object Evaluate(String value)
// Begin external code
Int32 _index = value.LastIndexOf('.');
String _retVal = value.Substring(_index + 1);
return _retVal;
// End external code
然后加载动态程序集并通过反射执行 Evaluate 方法。这很好用。
问题是恶意代码注入的可能性很大,所以我想在“沙盒”线程中运行 Evaluate 方法(没有任何非托管 API 调用)。 出于测试目的,我使用了内置的匿名 Windows 用户,并提供了以下代码:
Thread tSandbox = new Thread(
new ParameterizedThreadStart(this.DoSandboxedEvaluation));
WindowsIdentity tIdentity = WindowsIdentity.GetAnonymous();
WindowsPrincipal tPrincipal = new WindowsPrincipal(i);
这给了我匿名用户的身份和主体。如何将其应用于线程 tSandbox,以便该线程上的代码在指定的安全上下文中运行,而不使用非托管 API 调用?
谢谢!
【问题讨论】:
相关帖子here. 【参考方案1】:AFAIK 模拟另一个用户的唯一方法是通过非托管的 win32 api(例如,LogonUser())...您可以通过互操作调用它们。
有这个here的代码示例
【讨论】:
也许我应该提到我想避免非托管调用。我意识到我可以用 LogonUser 和所有的混乱来做这件事,但我想知道是否有一个“更好”的方法:p 无论如何谢谢。 是的。一个非常方便的nuget package 和the post 可以通过LogonUser()
实现相同的目的。【参考方案2】:
如果您只需要匿名帐户,您可能非常接近 - 您只需将原则分配给线程(您可以通过设置 System.Threading.CurrentPrinciple 来更改要更改的线程中运行的代码)
但是,如果您需要对 Windows 用户进行身份验证并将该身份分配给线程,我认为您将不得不对 LogonUser() 进行非托管调用。我看不出有什么办法。
这里有一些适用于匿名用户的代码(假设是一个 ASP.Net Web ApplicationProject,您在表单上有一个名为“identityLabel”的标签,并且您已分配 onInit="IdentityLabelInit") (请注意,代码的运行方式取决于您是在 IIS 下还是 Cassini 下运行 - 在 IIS 下,初始身份是匿名用户。在 Cassini 下,初始身份是我。
protected void IdentityLabelInit(object sender, EventArgs e)
System.Threading.Thread testThread = new Thread(ReportIdentity);
testThread.Start();
testThread.Join();
private void ReportIdentity()
identityLabel.InnerText = "Initialized: " + System.Threading.Thread.CurrentPrincipal.Identity.Name;
System.Security.Principal.IPrincipal currentPrincipal = System.Threading.Thread.CurrentPrincipal;
SetAnonymousIdentity();
System.Security.Principal.IPrincipal newPrincipal = System.Threading.Thread.CurrentPrincipal;
if (newPrincipal.Equals(currentPrincipal))
identityLabel.InnerText += ("no change");
else
identityLabel.InnerText += " | new name: " + System.Threading.Thread.CurrentPrincipal.Identity.Name;
private void SetAnonymousIdentity()
WindowsIdentity tIdentity = WindowsIdentity.GetAnonymous();
WindowsPrincipal tPrincipal = new WindowsPrincipal(tIdentity);
System.Threading.Thread.CurrentPrincipal = tPrincipal;
【讨论】:
以上是关于线程可以作为另一个用户执行吗? (.NET 2.0/3.5)的主要内容,如果未能解决你的问题,请参考以下文章