【问题标题】:Ensuring an assembly is called via a specified assembly确保通过指定的程序集调用程序集
【发布时间】:2011-02-20 14:55:49
【问题描述】:

是否有任何内置功能可以确定是否从特定程序集调用程序集?

我有程序集A,它引用了程序集B。程序集A 公开 PowerShell cmdlet 并输出在B 中找到的类型。由B 公开的某些方法和属性对程序集A 中的类型感兴趣,但对PowerShell 的消费者或任何试图直接在B 中加载类型并在其中调用方法的人不感兴趣。

我已经研究了InternalsVisibleToAttribute,但由于使用了接口,它需要大量的返工。我正在设计一个共享密钥系统,该系统后来会被混淆,但看起来很笨重。

有什么方法可以确保B 只被A 调用?

【问题讨论】:

  • 那么,为什么要强迫人们不要使用他们甚至不感兴趣的东西?
  • 而且,如果你想阻止人们做他们真正真正感兴趣的事情,这可能对一个甚至温和的对手都不起作用-- 替换程序集上的签名(使用来自不同密钥的签名)并更改任何硬编码的密钥以匹配......

标签: c# .net powershell assemblies


【解决方案1】:

您将在程序集上使用强名称键来执行此操作。

首先确保调用程序集(程序集 A)是强名称签名的(这可以在签名选项卡下的项目属性屏幕中完成)

以下代码将从调用程序集中检索强名称键。

internal static StrongName GetStrongName(Evidence evidence)
{
    foreach (var e in evidence)
    {
        if (e is StrongName)
        {
            return (StrongName)e;
        }
    }
    throw new ArgumentException();
}

最简单的方法是使用相同的 StrongName 对两个程序集进行签名,然后验证 Assembly.GetCallingAssembly().Evidence 和 Assembly.GetExecutingAssembly().Evidence 是否由相同的 StrongName 签名。

var callerKey = GetStrongName(Assembly.GetCallingAssembly().Evidence).PublicKey;
var execKey = GetStrongName(Assembly.GetExecutingAssembly().Evidence).PublicKey;

if (callerKey != execKey)
{
    throw new UnauthorizedAccessException("The strong name of the calling assembly is invalid.");
}

这在现有代码库上实现可能不切实际,但看看LinFu AOP,您应该能够实现一个可以附加到需要检查有效调用者的类的属性。

【讨论】:

    【解决方案2】:

    我认为InternalsVisibleToAttribute 是最好的选择。 Assembly.GetCallingAssembly的另一个选项检查

    【讨论】:

      猜你喜欢
      • 2018-05-03
      • 2012-01-01
      • 2010-09-06
      • 2014-06-07
      • 2010-09-30
      • 2018-06-11
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      相关资源
      最近更新 更多