C# 将方法中的代码限制为仅调用同一类中的成员

C# 将方法中的代码限制为仅调用同一类中的成员,c#,.net,code-security,C#,.net,Code Security,是否有一种方法可以限制在类中的一个方法中进行的调用,以便只能调用封闭类(也是继承的)上的方法和属性。我正在使用c#(.NET4.5)。这将用作我们的应用程序框架中的代码安全功能。您应该查看AppDomain沙箱。它允许您将插件加载到单独的AppDomain中,并以非常精细的级别分配执行权限 和 应该给你一个如何继续的想法。来自 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用System.IO; 使用系统安全; 使用系统

是否有一种方法可以限制在类中的一个方法中进行的调用,以便只能调用封闭类(也是继承的)上的方法和属性。我正在使用c#(.NET4.5)。这将用作我们的应用程序框架中的代码安全功能。

您应该查看AppDomain沙箱。它允许您将插件加载到单独的AppDomain中,并以非常精细的级别分配执行权限

和 应该给你一个如何继续的想法。

来自

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
使用系统安全;
使用系统、安全、策略;
使用System.Security.Permissions;
运用系统反思;
使用System.Runtime.Remoting;
//沙盒类需要从MarshallByRefObject派生
//这样我们就可以在另一个AppDomain中创建它并参考
//它将从默认的AppDomain中删除。
类沙盒:MarshalByRefObject
{
常量字符串pathToUntrusted=@“.\..\..\UntrustedCode\bin\Debug”;
常量字符串untrustedAssembly=“UntrustedCode”;
常量字符串untrustdclass=“untrustdcode.untrustdclass”;
常量字符串入口点=“IsFibonacci”;
私有静态对象[]参数={45};
静态void Main()
{
//设置AppDomainSetup。设置
//ApplicationBase中的文件夹,而不是
//沙盒驻留。
AppDomainSetup adSetup=新建AppDomainSetup();
adSetup.ApplicationBase=Path.GetFullPath(pathToUntrusted);
//正在设置AppDomain的权限。我们将授予该权限
//执行并读取/发现不受信任的
//代码已加载。
PermissionSet permSet=新的PermissionSet(PermissionState.None);
permSet.AddPermission(
新的SecurityPermission(SecurityPermissionFlag.Execution));
//我们需要沙盒程序集的强名称,以便添加
//将其添加到完全信任列表中。
StrongName fullTrustAssembly=
typeof(沙盒).Assembly.Evidence.GetHostEvidence();
//现在我们有了创建AppDomain所需的一切,
//让我们创建它。
AppDomain newDomain=AppDomain.CreateDomain(
“沙盒”,
无效的
安装,
置换,
(大会);
//使用CreateInstanceFrom加载沙盒类的实例
//进入新的AppDomain。
ObjectHandle=Activator.CreateInstanceFrom(
newDomain,
typeof(沙盒).Assembly.ManifestModule.FullyQualifiedName,
类型(沙盒)。全名);
//将新域实例展开为此域中的引用,然后
//使用它来执行不受信任的代码。
沙盒newDomainInstance=(沙盒)handle.Unwrap();
newDomainInstance.ExecuteUntrustedCode(
不可信的,
不可信的阶级,
入口点,
参数);
}
public void ExecuteUntrustedCode(
字符串assemblyName,
字符串类型名,
字符串入口点,
对象[]参数)
{
//加载新程序集中某个方法的MethodInfo。这可能是
//您知道的方法,也可以使用Assembly.EntryPoint访问
//可执行文件中的主函数。
MethodInfo目标=
Assembly.Load(assemblyName)
.GetType(typeName)
.GetMethod(入口点);
尝试
{
//现在调用该方法。
bool retVal=(bool)target.Invoke(null,参数);
}
捕获(例外情况除外)
{
//当我们从SecurityException额外打印信息时
//如果我们使用
//完全信任堆栈。
(新PermissionSet(PermissionState.Unrestricted)).Assert();
控制台写入线(
“捕获到SecurityException:\n{0}”,
ex);
CodeAccessPermission.RevertAssert();
Console.ReadLine();
}
}
}

我很好奇,想知道是否有人能想出一种方法来做到这一点(我想不出任何办法)。除了一般的代码安全性,我还想知道你的用例是什么。你使用的是什么版本的.NET?我们正在加载客户编写的插件,所以我想确保他们只执行“安全”的代码。您可以在一个特殊的
AppDomain
中运行它,如何在sanbox中运行部分受信任的代码->请注意,我想检查从我想“保护”的方法发出的调用,啊,很抱歉误解。更新答案。我已经更新了我的答案,使之更适合您的实际需要。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security;
using System.Security.Policy;
using System.Security.Permissions;
using System.Reflection;
using System.Runtime.Remoting;

// The Sandboxer class needs to derive from MarshalByRefObject
// so that we can create it in another AppDomain and refer to
// it from the default AppDomain.
class Sandboxer : MarshalByRefObject
{
    const string pathToUntrusted = @"..\..\..\UntrustedCode\bin\Debug";
    const string untrustedAssembly = "UntrustedCode";
    const string untrustedClass = "UntrustedCode.UntrustedClass";
    const string entryPoint = "IsFibonacci";
    private static Object[] parameters = { 45 };

    static void Main()
    {
        // Setting the AppDomainSetup. It is very important to set the
        // ApplicationBase to a folder other than the one in which
        // the sandboxer resides.
        AppDomainSetup adSetup = new AppDomainSetup();
        adSetup.ApplicationBase = Path.GetFullPath(pathToUntrusted);

        // Setting the permissions for the AppDomain. We give the permission
        // to execute and to read/discover the location where the untrusted
        // code is loaded.
        PermissionSet permSet = new PermissionSet(PermissionState.None);
        permSet.AddPermission(
            new SecurityPermission(SecurityPermissionFlag.Execution));

        // We want the sandboxer assembly's strong name, so that we can add
        // it to the full trust list.
        StrongName fullTrustAssembly =
            typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>();

        // Now we have everything we need to create the AppDomain so,
        // let's create it.
        AppDomain newDomain = AppDomain.CreateDomain(
                "Sandbox",
                null,
                adSetup,
                permSet,
                fullTrustAssembly);

        // Use CreateInstanceFrom to load an instance of the Sandboxer class
        // into the new AppDomain. 
        ObjectHandle handle = Activator.CreateInstanceFrom(
            newDomain,
            typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,
            typeof(Sandboxer).FullName);

        // Unwrap the new domain instance into a reference in this domain and
        // use it to execute the untrusted code.
        Sandboxer newDomainInstance = (Sandboxer)handle.Unwrap();
        newDomainInstance.ExecuteUntrustedCode(
            untrustedAssembly,
            untrustedClass,
            entryPoint,
            parameters);
    }

    public void ExecuteUntrustedCode(
            string assemblyName,
            string typeName,
            string entryPoint,
            object[] parameters)
    {
        // Load the MethodInfo for a method in the new Assembly. This might be
        // a method you know, or you can use Assembly.EntryPoint to get to the
        // main function in an executable.
        MethodInfo target =
            Assembly.Load(assemblyName)
               .GetType(typeName)
               .GetMethod(entryPoint);

        try
        {
            //Now invoke the method.
            bool retVal = (bool)target.Invoke(null, parameters);
        }
        catch (Exception ex)
        {
            // When we print informations from a SecurityException extra
            // information can be printed if we are  calling it with a
            // full-trust stack.
            (new PermissionSet(PermissionState.Unrestricted)).Assert();
            Console.WriteLine(
                "SecurityException caught:\n{0}",
                ex);
            CodeAccessPermission.RevertAssert();
            Console.ReadLine();
        }
    }
}