Wir verwenden ASP.NET mit vielen AJAX "Page Method" Aufrufen. Die auf der Seite definierten WebServices rufen Methoden aus unserer BusinessLayer auf. Um zu verhindern, dass Hacker die Seitenmethoden aufrufen, möchten wir eine Sicherheit im BusinessLayer implementieren.
Wir haben mit zwei verschiedenen Problemen zu kämpfen.
Erster:
%Vor%Diese Methode sollte von autorisierten Benutzern mit der Rolle "HR" aufgerufen werden.
Zweiter:
%Vor%Diese Methode sollte nur vom Besitzer des Auftrags aufgerufen werden.
Ich weiß, dass es einfach ist, die Sicherheit für jede Methode wie folgt zu implementieren:
%Vor%oder
%Vor%Nach was ich suche, ist ein Muster / Best Practice, um diese Art von Sicherheit auf generische Art und Weise zu implementieren (ohne das "wenn, dann jedes Mal") Ich hoffe du bekommst was ich meine: -)
Benutzer @mdma beschreibt ein bisschen über Aspect Oriented Programming. Dazu müssen Sie eine externe Bibliothek verwenden (wie zum Beispiel den großartigen PostSharp), da .NET nicht viel AOP-Funktionalität hat. .NET verfügt jedoch bereits über einen AOP-Mechanismus für rollenbasierte Sicherheit, der einen Teil Ihres Problems lösen kann. Sehen Sie sich das folgende Beispiel für Standard-.NET-Code an:
%Vor%Das PrincipalPermissionAttribute ist Teil von System.Security.Permissions Namespace und ist Teil von .NET (seit .NET 1.0). Ich verwende es bereits seit Jahren, um rollenbasierte Sicherheit in meinen Webanwendungen zu implementieren. Schön an diesem Attribut ist, dass der .NET JIT Compiler das Weben für Sie im Hintergrund erledigt und Sie sogar auf Klassenebene definieren können. In diesem Fall erben alle Mitglieder dieses Typs dieses Attribut und seine Sicherheitseinstellungen.
Natürlich hat es seine Grenzen. Ihr zweites Codebeispiel kann nicht mit dem rollenbasierten Sicherheitsattribut .NET implementiert werden. Ich denke, dass Sie mit dieser Methode einige benutzerdefinierte Sicherheitsüberprüfungen umgehen oder eine interne Sicherheitsbibliothek aufrufen können.
%Vor%Natürlich können Sie ein AOP-Framework verwenden, aber Sie müssten immer noch ein Framework-spezifisches Attribut schreiben, das wiederum Ihre eigene Sicherheitsebene aufruft. Dies würde nur dann nützlich sein, wenn ein solches Attribut mehrere Methodenaufrufe ersetzen würde, zum Beispiel, wenn Code in try, catch, finally-Anweisungen eingefügt werden muss. Wenn Sie einen einfachen Methodenaufruf ausführen würden, würde es keinen großen Unterschied zwischen einem einzelnen Methodenaufruf oder einem einzelnen Attribut-IMO geben.
Wenn Sie eine Auflistung von Objekten zurückgeben und alle Objekte ausfiltern möchten, für die der aktuelle Benutzer nicht über die erforderlichen Rechte verfügt, können LINQ-Ausdrucksbäume hilfreich sein:
%Vor%Wenn Ihr O / RM LINQ über Ausdrucksbäume (wie NHibernate, LINQ to SQL und Entity Framework) unterstützt, können Sie eine solche Sicherheitsmethode einmal schreiben und überall anwenden. Das Schöne daran ist natürlich, dass die Abfrage zu Ihrer Datenbank immer optimal ist. Mit anderen Worten, es werden keine weiteren Datensätze als benötigt abgerufen.
UPDATE (Jahre später):
Ich habe dieses Attribut lange Zeit in meiner Codebasis verwendet, aber vor einigen Jahren kam ich zu dem Schluss, dass Attribut-basiertes AOP schreckliche Nachteile hat. Zum Beispiel behindert es die Testbarkeit. Da der Sicherheitscode mit normalem Code verwebt ist, können Sie keine normalen Komponententests ausführen, ohne sich als gültiger Benutzer ausgeben zu müssen. Dies ist spröde und sollte im Unit-Test keine Rolle spielen (der Unit-Test selbst verletzt das Prinzip der einfachen Verantwortlichkeit). Außerdem zwingt es Sie dazu, Ihre Codebasis mit diesem Attribut zu belegen.
Anstatt also PrincipalPermissionAttribute
zu verwenden, verwende ich eher übergreifende Aspekte wie Sicherheit, indem ich Code mit Dekorateuren einpacke . Dies macht meine Anwendung viel flexibler und viel einfacher zu testen. Ich habe in den letzten Jahren mehrere Artikel über diese Technik geschrieben (zum Beispiel diese > und dieses hier ).
Eine "Best Practice" besteht darin, die Sicherheit zu einem Aspekt zu machen. Dadurch werden die Sicherheitsregeln von der primären Geschäftslogik getrennt, sodass keine Hardcodierung erforderlich ist und die Sicherheitsregeln in verschiedenen Umgebungen einfach geändert werden können.
Der folgende Artikel listet 7 Möglichkeiten auf, Aspekte zu implementieren und den Code getrennt zu halten. Ein Ansatz, der einfach ist und Ihre Business-Logik-Schnittstelle nicht ändert, ist die Verwendung eines Proxys. Dies stellt die gleiche Schnittstelle zur Verfügung, die Sie derzeit haben, ermöglicht jedoch eine alternative Implementierung, die die vorhandene Implementierung schmücken kann. Die Sicherheitsanforderungen können in diese Schnittstelle injiziert werden, entweder mit fest codierenden oder benutzerdefinierten Attributen. Der Proxy fängt Methodenaufrufe an Ihre Business-Schicht ab und ruft die entsprechenden Sicherheitsprüfungen auf. Das Implementieren von Interception über Proxies wird hier detailliert beschrieben - Entkoppeln von Komponenten durch Einfügen von benutzerdefinierten Diensten in die Aufrufkette Ihres Objekts . Andere AOP-Ansätze finden Sie in AOP in .NET verstehen .
Hier ist ein Forenbeitrag , in dem die Sicherheit als ein Aspekt diskutiert wird, mit Implementierung unter Verwendung von Ratschlägen und Sicherheitsattributen. Das Endergebnis ist
%Vor%Sie können das Attribut direkt auf Ihre Geschäftsmethode anwenden, eine enge Kopplung vornehmen oder einen Service-Proxy mit diesen Attributen erstellen, sodass die Sicherheitsdetails getrennt bleiben.
Tags und Links .net c# security design-patterns