2009-08-11 5 views
2

Angenommen, ich besitze eine Datenbank mit Büchern und Benutzern, und diese Benutzer haben bestimmte Berechtigungen für Bücher (wie Bearbeiten, Löschen usw.). Jetzt würde ich Methoden wie die folgende schreiben und dies als eine API und WebService verfügbar machen.Wie sollte man Berechtigungen für Objekte in .NET verwenden?

[WebMethod] 
Book GetBook(User login, int id) { 
    if (!CheckLogin(login)) 
     throw new Exception("Login error"); 

    return new Book(id); 
} 

Dies scheint alles in Ordnung, aber wie würde ich dieses Buch wieder speichern, wenn ich es geändert? Es fühlt sich richtig an, eine Save() Methode auf das Book-Objekt zu legen, da es (das Objekt) für sich selbst sorgen sollte. Aber die Überprüfung der Berechtigungen fühlt sich nicht richtig an. (Ich möchte nicht, dass das Buchobjekt etwas über Benutzer weiß)

Sollte ich SaveBook(Book book) wie Methoden erstellen, um dies zu tun?

Ist es trotzdem eine gute Idee, diesen Weg zu prüfen, wenn ein Benutzer eine Erlaubnis hat? Für einen WebService könnte ich mir vorstellen, dass es in Ordnung ist, aber ich habe Zweifel, ob dies als normale API (Assembly) verwendet wird.

Antwort

3

Sie sind über etwas namens Cross-Cutting-Concerns gestolpert ... Dinge in Ihrer App, die zusammenarbeiten müssen, aber logisch getrennt gehören. Protokollierung ist ein weiteres gängiges Beispiel.

Aspektorientierte Programmierung (AOP) bietet ein gutes Muster für die Trennung von Angelegenheiten wie Sicherheit von Geschäftsobjekten. Bei .Net ist PostSharp eine häufig verwendete AOP-Einrichtung.

+0

Das ist sehr interessant! Ich bin schon mal auf PostSharp gestoßen, konnte mir nur vorstellen, dass es für die Protokollierung nützlich ist. Ich sehe, dass ich Zugang zu den Parametern der Methode innerhalb des Aspekts habe, also würde ich immer noch den Benutzerparameter haben, benutze ihn einfach nicht innerhalb der Methode? –

+1

Der folgende Link zeigt ein empfohlenes Muster für die Autorisierung mit PostSharp. http://www.postsharp.org/aop-net/overview –

1

Web-Methode kann verwenden. NET-Mitgliedschaft-Engine, die (standardmäßig) auth Cookies erstellen. Beim nächsten Anruf müssen Sie nur überprüfen, ob der Benutzer bereits angemeldet ist. Denken Sie auch an den Standard-Autorisierungs-Webdienst, der das für Sie erledigt.

2

Es scheint mir, dass Sie Dienste definieren.

Sie sind wirklich nicht mit einzelnen Büchern mehr mit dem Satz von Büchern oder vielleicht eine Bibliothek, der soll, dass verschiedene Kategorien von Benutzern klar sein, es jetzt Dienste wie

addBookToLibrary(... details ...) 

borrowBook(Book) 

returnBook (Book) 

findBooks (... search criteria ...) 

reserveBook (Book, User, for how long) 

bieten würde tun werden autorisiert sein, verschiedene Methoden zu verwenden, können Bibliothekare mehr als die Mitglieder tun.

Dies bedeutet, dass wir für jede Anfrage wissen müssen, wer anruft. Oft ist diese authentifizierte Identität in irgendeiner Art von Kontext verfügbar, der unsichtbar an jedes Methood weitergegeben wird. [Deshalb habe ich die Benutzer-ID nicht als expliziten Parameter angegeben, außer in reserve() ... warum habe ich das gemacht?].

Ich denke, es ist sowohl für Web-Services als auch APIs sinnvoll, Autorisierungsregeln für solche Methoden zu haben.

+0

Das stimmt. In diesem Fall wäre es ein Service für die Interaktion mit Büchern, wie eine Bibliothek. Die von Ihnen angegebenen Methoden sind sinnvoll, aber wie wäre es mit einem Benutzer, der den Titel eines Buches ändern möchte? Würdest du buchen, book.Title = "newtitle", saveBook (Buch)? –

+0

Ich sehe immer noch, dass als Teil der Bibliothek, eine Methode wie updateBookInfo (ID, ... Details ...) – djna

+0

Okay, das ist, was ich zuerst dachte, auch "der" Weg zu sein. Dann habe ich begonnen, diese Update-Methode zu schreiben und es enthält eine Menge variabler Kopie wie persistedObj.Name = book.Name. Wie würden Sie Sammlungen innerhalb des Buches (wie Seiten) behandeln? Soll ich eine readonly-Liste in Book verwenden und ein AddPageToBook (b, p) in Library verwenden? Dies scheint Funktionalität zu ziehen, die in Buch zur Bibliothek gehört. –

1

Die Save() Methode auf Book klingt wie eine Verschmelzung von Bedenken, ein Objekt, das für zu viel verantwortlich ist.

Wenn Sie Save() anrufen, wie Sie richtig erkannt haben, müssen zahlreiche Dinge passieren, einschließlich der Berechtigungsprüfungen. Außerdem wird die Frage nach genau ausgelöst, wobei die Book Instanz gespeichert wird. Ein saubereres Design würde das Erstellen einer neuen Klasse beinhalten, die für das Laden und Speichern von Objekten und das Verarbeiten von Berechtigungsprüfungen als Teil des Prozesses verantwortlich ist. Ich empfehle Ihnen, ein wenig Lesen rund um die Repository-Muster, wie es eine gute Passform für Ihr spezielles Szenario sein könnte.

Sie sollten immer Berechtigungen überprüfen, bei denen Sicherheit eine Rolle spielt. Wenn Sie davon ausgehen, dass eine Komponente auf höherer Ebene Sie schützen wird, werden Sie wieder beißen, besonders wenn Sie Funktionen als Dienste und APIs offen legen! Wenn Sie das rollenbasierte Sicherheitssystem von .NET verwenden möchten, können Sie die Klasse PrincipalPermission (oder deren Attributäquivalent) verwenden, um Ihren aktuellen Benutzer in den erforderlichen Gruppen anzufordern. Dies wird eine Sicherheitsausnahme auslösen, wenn das aktuelle Prinzip die Aktion nicht ausführen darf.

Ich würde erwarten, um Erlaubnis-bezogene Ausnahmen zu sehen, die von den Methoden geworfen werden, in denen der aufrufende Benutzer nicht die korrekten Erlaubnis hatte, da sie den Grund für die Ausnahme offenbar kennzeichnen. Dies macht die Entwicklung gegen die API oder den Service viel einfacher.

Wer Ihre API oder Ihren Dienst aufruft, kann eigene Prüfungen durchführen, um sicherzustellen, dass der Prinzipal über die richtigen Berechtigungen verfügt, bevor er eine Aktion auslöst, die zu einer genehmigungsbezogenen Ausnahme im Produktionscode führen kann.

+0

Vielen Dank für diese gute Antwort. Ich lese mehr über das Repository-Muster, sehr hilfreich! –

Verwandte Themen