Вопрос

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

  private static void TargetMethod()
  {
  }

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

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

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

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

Это было полезно?

Решение

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top