【问题标题】:access private method in a different assembly c#在不同的程序集中访问私有方法c#
【发布时间】:2010-10-26 18:24:33
【问题描述】:

这可能是一个愚蠢的问题,因为我可以看到它以这种方式发生的安全原因......

我有一个许可 c# 项目,它有一个类,它有一个生成我的许可证密钥的方法。我已将此方法设为私有,因为我不希望其他人能够出于明显的原因调用我的方法

我想做的下一件事是拥有我的用户界面,它位于另一个 c# 项目中,该项目引用许可 dll 是唯一可以在自身之外访问此方法的其他“事物”,这可能吗?我是否需要将它移到同一个项目中,以便它全部编译到同一个 dll 并且我可以访问它的成员?

许可项目
-许可类
--Private MethodX (GeneratesLicenseKeys)

LicensingProject.UI
-LicensingUiClass
--我希望能够成为唯一能够访问MethodX的类

许可证密钥生成器不只是在 UI 中是有原因的,因为许可通过在自身上生成哈希并将其与许可证生成器生成的哈希进行比较来工作。

我不希望全部编译为 dll,因为我的最终用户不需要 UI 代码。

我知道按照常识,私有方法就是这样。我被难住了。

【问题讨论】:

    标签: c# namespaces private


    【解决方案1】:

    您可以将其设为内部方法,并使用 InternalsVisibleToAttribute 为 LicensingProject.UI 提供对 LicensingProject 的额外访问权限。

    Merhdad 关于执法的观点是对的,也是错的。如果你没有ReflectionPermission,CLR 会阻止你调用你不应该调用的东西——但如果你使用来自完全受信任的程序集的反射,你可以调用任何东西。你应该假设一个潜在的黑客能够在他自己的机器上运行一个完全受信任的程序集:)

    这些都不会阻止某人使用Reflector 来反编译您的代码。换句话说,将其设为私有并没有真正为您的许可方案增加大量安全性。如果有人真的努力打破它,他们可能能够做到。

    【讨论】:

    • 我认为 CLR 不会阻止您调用私有方法。当然,如果方法有你不能满足的 CAS 要求,你就不能调用它。只要您拥有 ReflectionPermission,我认为您可以调用任何私有方法(不需要任何其他权限)。如果我错了,请纠正我...
    • ReflectionPermission 是我的想法。没有它,您仍然可以通过反射调用公共成员。但是,是的,实际上并不需要完全信任 - 将进行编辑。
    • 感谢 Jon 和 Mehrdad 的回答。
    【解决方案2】:

    这确实是一条评论,以回应 Mehrdad 关于运行时不执行访问检查的观点;在这里,您可以看到 JIT(它发生)执行访问检查 - 不是反射,也不是 C# 编译器。

    要修复代码,请将Foo.Bar 公开。有趣的是,它还验证了Foo 是可访问的——所以将Foo 设为内部以查看更多烟花:

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    static class Program {
        static void Main() {
            MethodInfo bar = typeof(Foo).GetMethod("Bar",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            var method = new DynamicMethod("FooBar", null, new[] {typeof(Foo)});
            var il = method.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.EmitCall(OpCodes.Callvirt, bar, null);
            il.Emit(OpCodes.Ret);
    
            Action<Foo> action = (Action<Foo>) method.CreateDelegate(typeof(Action<Foo>));
            Foo foo = new Foo();
            Console.WriteLine("Created method etc");
            action(foo); // MethodAccessException
        }
    }
    
    public class Foo {
        private void Bar() {
            Console.WriteLine("hi");
        }
    }
    

    【讨论】:

    • 老实说,我了解的不多!不过,我会尽力理解它。我喜欢人们比最初的问题更深入,为 SO 及其用户 +1!
    【解决方案3】:

    public, private, ... 东西只是由编译器强制执行的。您可以使用反射很容易地访问它们(假设代码具有所需的权限,这是一个合理的假设,因为他可以完全控制机器)。不要依赖这个假设没有人可以调用它。

    【讨论】:

    • 不正确;它们也由反射和 CLI 强制执行 - 只是你经常以完全信任的方式运行,所以你不会注意到它......但这不应该假设
    • (正如您在 Jon 的帖子中所指出的 - ReflectionPermission)
    • @Marc:我认为 CLR 不会强制执行任何调用私有方法的操作。我更新了我的答案以反映争议。我不是 100% 确定我说什么。我很乐意得到纠正。
    • 基于通过 Reflection.Emit 编写一些代码(在运行时)既不使用反射也不使用 C# 编译器,我很确定它确实如此......不过,我会尝试调查。
    • 我在回复中添加了这方面的证据
    【解决方案4】:

    Foo.Bar 可以保持私有... 要修复上面的代码,在 DynamicMethod 构造函数的末尾添加一个参数:

    var method = new DynamicMethod("FooBar", null, new[] {typeof(Foo)}, true);
    

    添加 true 以跳过对动态方法的 MSIL 访问的类型和成员的 JIT 可见性检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多