Как запретить вызов метода C#

Я хочу разрешить вызов метода только из определенных методов. Посмотрите на код ниже.

  private static void TargetMethod()
  {
  }

  private static void ForbiddenMethod()
  {
     TargetMethod();
  }

  private static void AllowedMethod()
  {
     TargetMethod();
  }

Мне нужно только AllowedMethod может вызвать TargetMethod. Как это сделать с помощью классов из System.Security.Permissions?

Обновлено: спасибо за ваши ответы, но я не хочу спорить о дизайне моего приложения. Я просто хочу знать, возможно ли это сделать с помощью.net security или нет?

7 ответов

Решение

CAS не может сделать это, если код работает с полным доверием.

Если код выполняется в режиме полного доверия (т. Е. Обычное локальное приложение, а не приложение silverlight или что-то запускаемое из сети), то все проверки.NET CAS полностью игнорируются; любой атрибут безопасности просто игнорируется.

CAS просто обходит стек, чтобы определить разрешения, и вы можете сделать это тоже, как указывал ранее Дарин, просто проверив StackTrace,

Вы можете решить это, используя обычный объектно-ориентированный дизайн. Переехать AllowedMethod в новый класс и сделать ForbiddenMethod приватный метод этого класса:

public class MyClass
{
    public void AllowedMethod() { // ... }

    private void TargetMethod() { // ... }
}

AllowedMethod имеет доступ к закрытым членам, но никто другой не имеет.

Я считаю, что вы должны попытаться структурировать свой код в значимых классах и использовать стандартные модификаторы доступа (private, protected, public, internal). Есть ли какая-то конкретная причина, по которой это не решило бы вашу проблему?

Единственная альтернатива, о которой я могу подумать, - это прохождение стека вызовов внутри вызываемого абонента, но это, скорее всего, приведет к путанице кода и неоптимальной производительности.

Вы можете проверить стек вызовов для достижения этой цели, но это довольно медленно. Я не рекомендовал бы это, если этого можно избежать.

Если вы все еще хотите это сделать, вам следует быть осторожным, чтобы избежать встраивания методов, иначе ваш код может внезапно перестать работать в сборках Release.

[MethodImpl(MethodImplOptions.NoInlining)]
private static void TargetMethod()
{
    StackFrame fr = new StackFrame(1, false);
    Console.WriteLine(fr.GetMethod().Name);
}

Насколько я знаю, нет никаких готовых атрибутов для этого.

Я не уверен, что это достижимо с System.Security.Permissions, но внутри TargetMethod Вы можете получить звонящего и действовать соответственно:

StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);

Возможно, вы сможете использовать объекты CodeAccessPermission. Вы должны будете реализовать интерфейс в своем собственном объекте, чтобы он работал так, как вы предлагаете.

http://msdn.microsoft.com/en-us/library/system.security.codeaccesspermission.aspx

Используя атрибуты, вы можете решить эту проблему.

Используйте условные атрибуты.

На вершине

#define "Show" 


  public void TargetMethod()
    {
      //Code
    }
   [ Conditional("Hidden")]
   public void HiddenMethod()
    {
       TargetMethod()
    }
 [ Conditional("Show")]
  public void AllowMethod()
    {
       TargetMethod()
    }

Будет назван один из ваших методов.

Другие вопросы по тегам