2009-05-16 9 views
2

Это может быть Daft вопрос, как я могу видеть причину безопасности, чтобы это произошло так, как это делает ...доступа частный метод в различной комплектации с #

У меня есть лицензирование C# проекта, это имеет класс который имеет метод, который генерирует мои лицензионные ключи. Я сделал этот метод приватным, так как я не хочу, чтобы кто-либо еще мог вызвать мой метод по очевидным причинам.

Следующее, что я хочу сделать, - это иметь мой пользовательский интерфейс, который находится в другом проекте C#, который ссылается лицензирующая dll будет единственной другой «вещью», которая может получить доступ к этому методу вне себя, это возможно или мне нужно переместить его в один и тот же проект, чтобы он все скомпилировался в одну и ту же DLL, и я могу получить доступ к ее членам?

LicensingProject
-LicensingClass
--private MethodX (GeneratesLicenseKeys)

LicensingProject.UI
-LicensingUiClass
--Я хочу, чтобы иметь возможность быть единственным классом, чтобы иметь возможность доступ MethodX

Существует причина, по которой лицензионный ключ-генератор не только в пользовательском интерфейсе, лицензирование работает, генерируя хеш сам по себе и сравнивает его с тем, который генерируется Генератором лицензий.

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

Я знаю, что здравым смыслом используется частный метод. Я в тупике.

ответ

6

Вы можете сделать это внутренним методом и использовать InternalsVisibleToAttribute, чтобы предоставить LicensingProject.UI дополнительный доступ к LicensingProject.

Точка Мерддада о правоприменении правильная и неправильная одновременно. Если у вас нет ReflectionPermission, CLR перестанет вам называть то, что вам не нужно, но если вы используете отражение от полностью доверенной сборки, вы можете позвонить что угодно. Вы должны предположить, что потенциальный хакер может запустить полностью доверенную сборку на своем собственном компьютере.

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

+1

Я не думаю, что CLR перестанет называть частные методы. Конечно, если у метода есть требования CAS, которые вы не можете удовлетворить, вы не сможете его назвать. Пока у вас есть ReflectionPermission, я думаю, вы можете вызвать любой закрытый метод (который не требует каких-либо других разрешений). Исправьте меня, если я ошибаюсь ... –

+0

ReflectionPermission - это то, о чем я думал. Без этого вы все равно можете вызвать публичных членов путем размышления. Но да, на самом деле это не полное доверие, которое требуется - будет редактировать. –

+0

Спасибо за ответы как на Джон, так и на Мехрдада. –

2

public, private ... материал компилятором просто выполняется. Вы можете использовать отражение, чтобы получить доступ к ним довольно легко (при условии, что код имеет необходимые разрешения, что является разумным предположением, поскольку он имеет полный контроль над машиной). Не полагайтесь на то, что никто не может назвать это.

+0

Не верно; они выполняются как в отражении, так и в CLI - просто, что вы часто работаете с полным доверием, поэтому вы этого не замечаете ... но это не следует предполагать –

+0

(как вы заметили на пост Джона - ReflectionPermission) –

+0

@Marc: Я не думаю, что CLR навязывает что-либо для вызова частного метода. Я обновил свой ответ, чтобы отразить противоречие. Я не уверен на 100% о том, что я говорю. Я буду рад, если вас исправит. –

2

Это действительно комментарий, в ответ на точку зрения Мехрдада о времени выполнения, не выполняющем проверки доступа; здесь вы можете увидеть 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"); 
    } 
} 
+0

Интересно, действительно. +1 –

+0

Буду честным, я понимаю, что это не так! Я постараюсь сделать все возможное, чтобы понять это. Мне нравится, когда люди идут глубже, чем только начальный вопрос +1 к SO и его пользователям! –

+1

@Phill - слишком много Reflection.Emit может уничтожить ум ... –

1

Foo.Bar может остаться частным ... Чтобы исправить код, указанный выше, добавить один параметр в конце DynamicMethod конструктора :

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

Добавить верно пропустить видимость JIT проверок типов и членов, доступ к которым MSIL динамического метода.

 Смежные вопросы

  • Нет связанных вопросов^_^