2008-10-04 17 views
5

Publishing- und/oder gemeinschaftliche Anwendungen beinhalten häufig die gemeinsame Nutzung von Ressourcen. In einem Portal kann einem Benutzer Zugriff auf bestimmte Inhalte als Mitglied einer Gruppe oder auf expliziten Zugriff gewährt werden. Der vollständige Inhalt kann öffentliche Inhalte, Gruppenmitgliedschaftsinhalte und private Benutzerinhalte umfassen. Oder mit Collaboration-Anwendungen möchten wir vielleicht Ressourcen als Teil eines Workflows weitergeben oder das Sorgerecht für ein Dokument zur Bearbeitung freigeben.Was sind die besten Vorgehensweisen bei der Autorisierung von Ressourcenlisten?

Da die meisten Anwendungen diese Ressourcen in einer Datenbank speichern, erstellen Sie in der Regel Abfragen wie "Alle Dokumente abrufen, die ich bearbeiten kann" oder "Alle Inhalte abrufen, die ich sehen kann". Wo 'bearbeiten' und 'sehen können' sind die Benutzerrechte.

Ich habe zwei Fragen:

  1. Es ist ziemlich einfach, den Benutzer zu autorisieren, wenn Sie eine Ressource abgerufen haben, aber wie Sie effizient Autorisierung auf der Liste der verfügbaren Ressourcen durchführen? Und,

  2. Kann diese Art von Autorisierung vom Kern der Anwendung getrennt werden? Vielleicht in einen separaten Dienst? Wie können Sie nach der Trennung Suchanfragen filtern wie "Holen Sie mir alle Dokumente, die ich mit einem Titel wie [SomeSearchTerm] sehen kann"? Es scheint mir, dass Ihr separates System viele Referenzdaten kopieren müsste.

Antwort

0

ich haben in der Regel ein Schema ähnliche

Benutzer − − ∈ Userdocuments ∋ − − Dokumente

Dann erstelle ich einen Blick "ProfiledDocuments"

SELECT <fields> 
FROM Documents d 
INNER JOIN UserDocuments ud on ud.DocumentId = d.Id 
INNER JOIN Users u ON u.Id = ud.UserId 

dann die Suche ausführen Abfragen von ProfiledDocuments, die immer eine UserId-Datei verwenden er. Mit entsprechenden Indizes funktioniert es gut genug.

Wenn Sie komplexere Berechtigungen benötigen, können Sie dies mit einem zusätzlichen Feld in der Tabelle UserDocuments many to man tun, die die Art der Berechtigung angibt.

0

Obwohl Ihre Frage ziemlich ausgearbeitet ist, gibt es tatsächlich einen fehlenden Kontext.
Was definiert die Dokumente, für die ein Benutzer Privilegien hat? Kann ein Benutzer nur seine "eigenen" Dateien bearbeiten? Gibt es hier einen rollenbasierten Mechanismus? Ist es mehr MAC-orientiert (d. H. Ein Benutzer kann ein Sicherheitsniveau sehen)? Gibt es ein definierendes Attribut für die Daten (z. B. Abteilung)?

All diese Fragen zusammen ergeben ein besseres Bild und erlauben eine spezifischere Antwort.

Wenn Dokumente von einem bestimmten Benutzer "gehört" werden, ist es ziemlich einfach - haben Sie ein "Besitzer" -Feld für das Dokument. Suchen Sie dann nach allen Dokumenten, die dem Benutzer gehören.
Wenn Sie die Liste der benannten Benutzer (oder Rollen), auf die Zugriff besteht, vorab definieren können, können Sie eine Liste zwischen den Dokumenten, der Liste der autorisierten Benutzer/Rollen und dem Benutzer (oder seinen Rollen) abfragen. .
Wenn ein Benutzer Berechtigungen entsprechend seiner Abteilung (oder eines anderen ähnlichen Dokuments Attribut) erhält, können Sie darauf abfragen.
In ähnlicher Weise können Sie nach allen Dokumenten mit einer Sicherheitsstufe suchen, die gleich oder niedriger als die der Benutzerprivilegien ist. Wenn dies ein dynamischer Workflow ist, sollte jedes Dokument in der Regel mit dem aktuellen Status und/oder dem nächsten erwarteten Schritt markiert werden. Welche Benutzer den nächsten Schritt ausführen können, ist einfach eine weitere Berechtigung/Rolle (behandle dasselbe wie oben).
Dann, natürlich, sollten Sie eine UNION ALL zwischen allen und öffentlichen Dokumenten tun ...

Btw, wenn ich es nicht klar gemacht habe, ist dies keine einfache Frage - selbst einen Gefallen tun und finden Sie vorgefertigte Infrastruktur, um es für Sie zu tun. Selbst auf Kosten der Vereinfachung Ihrer Autorisierungsschemata.

5

Das könnte Sie interessieren: this article by Steffen Bartsch. Es fasst alle Autorisierungs-Plugins für Ruby on Rails zusammen und ich bin sicher, dass es Ihnen helfen wird, Ihre Lösung zu finden (obwohl dieser Artikel sich mit Rails-Plugins befasst, können die Konzepte leicht außerhalb von Rails exportiert werden).

Steffen auch sein eigenes Plugin gebaut "deklarative Authorization" genannt, die Ihren Bedürfnissen zu entsprechen scheint, IMHO:

  • auf der einen Seite definieren Sie Rollen (wie "Besucher", „admin "...). Ihre Benutzer sind diesen Rollen zugeordnet (in einer Viele-zu-Viele-Beziehung). Sie ordnen diese Rollen Berechtigungen zu (wieder in einer Viele-zu-viele-Beziehung). Jedes Privileg ist mit einem gegebenen Kontext verknüpft. Zum Beispiel kann die Rolle "Besucher" die Berechtigung "Dokumente lesen" haben. In diesem Beispiel ist "lesen" das Privileg, und es wird auf den "Dokumente" Kontext angewendet.
  • Hinweis: In Steffens Plugin können Sie eine Rollenhierarchie definieren. Zum Beispiel könnten Sie die „global_admin“ Rolle gehören die „document_admin“ Rolle, sowie die „comment_admin“ Rolle usw.
  • Sie auch definiert, kann Hierarchien von Privilegien haben wollen: zum Beispiel, die "verwalten" Privileg umfassen könnte die "lesen", "Update", "hinzufügen" und Privilegien " löschen".
  • auf der anderen Seite, können Sie Ihre Anwendung in Bezug auf Privilegien und Kontexte in Bezug auf den Rollen, nicht denken, codieren. Beispielsweise sollte die Aktion zum Anzeigen eines Dokuments nur prüfen, ob der Benutzer die Berechtigung "lesen" im Kontext "Dokumente" hat (keine Überprüfung, ob der Benutzer die Rolle "Besucher" oder eine andere hat andere Rolle). Dies vereinfacht Ihren Code erheblich, da der Großteil der Berechtigungslogik an anderer Stelle extrahiert (und möglicherweise sogar von jemand anderem definiert) wird.
  • Diese Trennung zwischen der Definition der Benutzerrollen und der Definition der Berechtigungen auf Anwendungsebene garantiert, dass sich Ihr Code nicht jedes Mal ändert, wenn Sie eine neue Rolle definieren.Zum Beispiel, hier ist, wie einfach die Zugangskontrolle wie in einem Controller aussehen:

    class DocumentController [...] 
        filter_access_to :display, :require => :read 
        def display 
        ... 
        end 
    end 
    

    Und in einer Ansicht.

    <html> [...] 
        <% permitted_to?(:create, :documents) do %> 
        <%= link_to 'New', new_document_path %> 
        <% end %> 
    </html> 
    

    Steffen Plugin ermöglicht auch auf Objektebene (dh zeilen- Level) Zugriffskontrolle. Zum Beispiel möchten Sie vielleicht eine Rolle wie „document_author“ und geben definieren „verwalten“ Privileg auf „Dokumente“, aber nur, wenn der Benutzer die Verfasser des Dokuments ist. Die Deklaration dieser Regel würde wahrscheinlich so aussehen:

    role :document_author do 
        has_permission.on :documents do 
        to :manage 
        if_attribute :author => is {user} 
        end 
    end 
    

    Das ist alles, was es ist! Sie können nun alle Dokumente, die der Benutzer so zu aktualisieren, ist erlaubt:

    Document.with_permissions_to(:update) 
    

    Da die „verwalten“ Privileg der „Update“ Privileg enthält, wird dies die Liste der Dokumente zurück, deren Autor ist der aktuelle Benutzer.

    Natürlich wird nicht jede Anwendung dieses Maß an Flexibilität benötigen ... aber deins könnte.

    Verwandte Themen