简体   繁体   English

线程可以作为其他用户执行吗? (.NET 2.0 / 3.5)

[英]Can a Thread be executed as another user? (.NET 2.0/3.5)

I have a C# application the performs some runtime compilation of source files containing calculations into dynamic assemblies. 我有一个C#应用程序,可以对包含计算到动态程序集的源文件进行一些运行时编译。 Obviously this presents a serious security issue. 显然,这带来了严重的安全问题。

From the following 'formula', the code below would be generated, and a dynamic assembly created: 根据以下“公式”,将生成以下代码,并创建一个动态程序集:

Formula: 式:

Int32 _index = value.LastIndexOf('.');
String _retVal = value.Substring(_index + 1);
return _retVal;

Code Generated: 生成的代码:

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
    }
  }
}

The dynamic assembly is then loaded and the Evaluate method executed via Reflection. 然后加载动态程序集,并通过反射执行Evaluate方法。 This works Great. 这很好。

The problem is that the potential for malicious code injection is huge, so I want to run the Evaluate method in a 'Sandboxed' thread (without any unmanaged API calls). 问题在于恶意代码注入的可能性很大,因此我想在“沙盒”线程中运行Evaluate方法(不进行任何非托管API调用)。 For testing purposes I'm using the built in Anonymous Windows user, and have come up with the following code: 为了进行测试,我使用了内置的Windows匿名用户,并提供了以下代码:

Thread tSandbox = new Thread(
    new ParameterizedThreadStart(this.DoSandboxedEvaluation));
WindowsIdentity tIdentity = WindowsIdentity.GetAnonymous();
WindowsPrincipal tPrincipal = new WindowsPrincipal(i);

This gives me the Anonymous users' Identity and Principal. 这给了我匿名用户的身份和主体。 How can this be applied to thread tSandbox so the code on that thread runs in the specified Security Context, without using Unmanaged API calls? 如何将此方法应用于线程tSandbox,以便该线程上的代码在指定的安全上下文中运行,而无需使用非托管API调用?

Thanks! 谢谢!

AFAIK the only way to impersonate another user is via the unmanaged win32 apis (eg, LogonUser())... You can call them through interop. AFAIK模仿其他用户的唯一方法是通过不受管理的win32 api(例如LogonUser())...您可以通过互操作调用它们。

There's a code sample of this here 有这样一个代码示例在这里

If you only need the anonymous account, you might be pretty close -- you just need to assign the principle to the thread (you do this from code running within the thread that you want to change by setting System.Threading.CurrentPrinciple) 如果您只需要匿名帐户,则您可能已经很接近了-您只需将原理分配给线程(您可以通过设置System.Threading.CurrentPrinciple,在要更改的线程中运行的代码来完成此工作)

However, if you need to authenticate a Windows user and assign that identity to the thread, I think that you are going to have to make an unmanaged call to LogonUser(). 但是,如果您需要验证Windows用户并将该身份分配给线程,我认为您将不得不对LogonUser()进行非托管调用。 I don't see a way around that. 我没有办法解决。

Here's some code that works with the anonymous user (it assumes an ASP.Net Web ApplicationProject, where you have a tag on the form named "identityLabel", and you have assigned onInit="IdentityLabelInit") (note the code runs differently depending upon whether you are running it under IIS or Cassini -- under IIS, the initial identity is the anonymous user. Under Cassini, the initial identity was me. 这是一些与匿名用户一起使用的代码(假定使用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;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM