2009-05-16 6 views
2

Cela peut être une question stupide que je peux voir la raison de la sécurité pour que cela arrive comme il le fait ...d'accès dans un assemblage différent C#

J'ai un projet de licence de C#, ce qui a une classe qui a une méthode qui génère mes clés de licence. J'ai rendu cette méthode privée car je ne veux pas que quelqu'un d'autre puisse appeler ma méthode pour des raisons évidentes

La prochaine chose que je veux faire est d'avoir mon interface utilisateur, qui est dans un autre projet C# qui fait référence la licence dll est la seule autre chose qui peut accéder à cette méthode en dehors de lui-même, est-ce possible ou dois-je la déplacer dans le même projet pour que tout compile vers la même DLL et que je puisse accéder à ses membres?

LicensingProject
-LicensingClass
--Private MethodX (GeneratesLicenseKeys)

LicensingProject.UI
-LicensingUiClass
-I veulent être en mesure d'être la seule classe de pouvoir accès MethodX

Il y a une raison pour laquelle le générateur de clé de licence n'est pas seulement dans l'interface utilisateur, c'est parce que la licence fonctionne en générant un hachage sur lui-même et le compare à celui généré par le générateur de licence.

Je préférerais ne pas tous compiler à la DLL car mes utilisateurs finaux n'ont pas besoin du code d'interface utilisateur. Je sais que par bon sens une méthode privée est juste cela. Je suis perplexe.

Répondre

6

Vous pouvez en faire une méthode interne et utiliser InternalsVisibleToAttribute pour accorder à LicensingProject.UI un accès supplémentaire à LicensingProject.

Le point de Merhdad sur l'application est juste et faux en même temps. Si vous n'avez pas ReflectionPermission, le CLR vous empêchera d'appeler des choses que vous ne devriez pas faire - mais si vous utilisez le reflet d'un assemblage entièrement approuvé, vous pouvez appeler n'importe quoi. Vous devez supposer qu'un pirate potentiel est capable d'exécuter un assembly entièrement sécurisé sur sa propre machine :)

Rien de tout cela n'empêchera quelqu'un d'utiliser Reflector pour décompiler votre code. En d'autres termes, le rendre privé n'est pas vraiment ajoutant une quantité significative de sécurité à votre régime de licences. Si quelqu'un essaie vraiment de le casser, il sera probablement capable de le faire.

+1

Je ne pense pas que CLR vous empêchera d'appeler des méthodes privées. Certes, si la méthode a des exigences CAS que vous ne pouvez pas satisfaire, vous ne serez pas en mesure de l'appeler. Tant que vous avez ReflectionPermission, je pense que vous pouvez appeler n'importe quelle méthode privée (qui ne nécessite aucune autre autorisation). Corrigez-moi si je me trompe ... –

+0

ReflectionPermission est ce que je pensais. Sans cela, vous pouvez toujours appeler les membres du public par la réflexion. Mais oui, ce n'est pas la confiance totale qui est nécessaire - sera éditer. –

+0

Merci pour les réponses à Jon et Mehrdad. –

2

public, private, ... les éléments sont simplement appliqués par le compilateur. Vous pouvez utiliser la réflexion pour y accéder assez facilement (en supposant que le code ait les permissions requises, ce qui est une hypothèse raisonnable car il a un contrôle complet sur la machine). Ne comptez pas sur cela en supposant que personne ne peut l'appeler.

+0

Non true; ils sont appliqués aussi bien par la réflexion que par la CLI - simplement que vous utilisez souvent la confiance totale, donc vous ne le remarquez pas ... mais cela ne doit pas être supposé –

+0

(comme vous le notez sur le post de Jon - ReflectionPermission) –

+0

@ Marc: Je ne pense pas que CLR applique quoi que ce soit pour appeler une méthode privée. J'ai mis à jour ma réponse pour refléter la controverse. Je ne suis pas sûr à 100% de ce que je dis. Je serai heureux d'être corrigé. –

2

Ceci est vraiment un commentaire, en réponse à l'argument de Mehrdad sur le fait que l'exécution ne vérifie pas les accès; ici, vous pouvez voir le JIT (il transpire) effectuer la vérification d'accès - pas de réflexion, et pas le compilateur C#.

Pour corriger le code, rendez Foo.Bar public.Fait intéressant, il vérifie également que Foo est accessible - alors assurez-Foo interne pour plus de feux d'artifice:

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

Intéressant en effet. +1 –

+0

Je vais être honnête, je ne comprends pas beaucoup de ça! Je vais essayer de faire de mon mieux pour le comprendre. Je l'aime quand les gens vont plus loin que la question initiale, +1 à SO et à ses utilisateurs! –

+1

@Phill - trop de Reflection.Emit peut détruire l'esprit ... –

1

Foo.Bar peut rester privé ... Pour corriger le code ci-dessus, ajouter un paramètre à la fin du constructeur DynamicMethod :

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

Ajouter true pour ignorer les contrôles de visibilité JIT sur les types et les membres accédés par le MSIL de la méthode dynamique.

Questions connexes