Warning: include_once(/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php): failed to open stream: No such file or directory in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: include_once(): Failed opening '/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php' for inclusion (include_path='.:/opt/php/lib/php') in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/fields/dbp11/local/config.php:4) in /var/www/html/pmwiki-2.2.86/pmwiki.php on line 1250
Datenbankpraktikum SS 2011 - Controller - Rechte

Rechteverwaltung:

Die Rechteverwaltung von angemeldeten Nutzern haben wir mithilfe des Ruby on Rails Gems CanCan implementiert. Die Unterscheidung zwischen nicht angemeldeten und angemeldeten Nutzern übernimmt bei uns hingegen das Devise Authentifizierungs-Gem, wobei wir allerdings auf dieses nicht weiter eingehen, da nach der Installation nur sehr geringfügige Anpassungen notwendig waren.

CanCan

CanCan ist ein Ruby on Rails Autorisierungs-Gem, welches vornehmlich mit dem Schlüsselwort „can“ und einer „ability“ genannten Klasse arbeitet. Mit dem Schlüsselwort „can“ kann man die von dem jeweiligen User nutzbaren Controller festlegen, was wie folgt in der Implementierung aussieht:

 can :index, :all

Der vorliegende Befehl bedeutet, dass man alle Index-Controller-Methoden nutzen kann. Man gibt also nach dem Schlüsselwort „can“ zuerst die Controller-Methode an und dann für welche Controller die vorangegangene Autorisierung gelten soll. Alternativ zur expliziten Angabe aller nutzbaren Controller-Methoden können vordefinierte Zusammenfassungen von mehreren Standard-Controllern genutzt werden: read: fasst die Index- und die Show-Methoden zusammen create: fasst die New- und die Create-Methoden zusammen manage: fasst alle Methoden zusammen

Der „cannot“-Befehl überschreibt ein bewilligtes „can“ wieder, sodass Ausnahmen von „manage“ eingefügt werden können.

Mithilfe von Schleifen oder durch im Modell definierte Bedingungen, welche Untermengen einer Entität identifizieren, kann man zusätzlich spezielle Bedingungen für die Controller-Zugriffe stellen:

 can [:show, :update, :destroy], Car do |car|
  car && car.user == user
 end

 can :show, user.get_visible_cars

Diese Zeilen sind die Festlegung der Zugriffsberechtigungen für die Autos in unserer Anwendung. Zum einen können Nutzer auf ihre eigenen Autos zugreifen und zum anderen können sie die Autos sehen, welche in angebotenen Fahrten verwendet werden. Spezielle Bedingungen können auch mithilfe von Hashes hinzugefügt werden. So könnte man zum Beispiel einem Objekt verschiedene Prioritäten zuweisen. Je nach Priorität wird allen Nutzern, den Moderatoren oder nur dem Administrator Zugriff gewährt:

 can :read, Project, :priority => 1..3

Dieses Beispiel bedeutet, dass der entsprechende User Zugriff auf die Controller-Methoden „index“ und „show“ von allen Projekten mit der Priorität 1-3 möglich ist. Dies hätten wir in unserem Projekt vielleicht anstelle der Konstanten-Lösung bei der Unterscheidung der verschiedenen Trip-Rollen nutzen können, indem wir den verschiedenen Positionen jeweils eine Zahl zugeordnet hätten, welche dann von der View spezifisch hätte abgefragt werden können. Allerdings empfanden wir diese Lösung zu diesem Zeitpunkt als wenig einleuchtend und haben uns deswegen für die schon beschriebene Lösung entschieden. Vom Vorgehen bezüglich der Rollen- und Rechteverwaltung her wäre dies in sich wohl konsistenter gewesen.

Nutzung und Abfrage der definierten Rechte: Dies kann zum einen mithilfe einer spezifischen Abfrage mit dem Schlüsselwort „can?“ geschehen, was vor allem in der View und im Controller in Form von if-Abfragen erfolgt. Dabei wird zum Beispiel entschieden, ob ein bestimmter Button nur für jemanden erscheint, der das Recht hat eine bestimmte Entität zu aktualisieren. Es kann außerdem abgefragt werden, ob demjenigen der eine Entität aktualisieren kann, mehr Informationen übergeben werden sollen oder ob unterschiedlich auf die Eingaben von Nutzern mit verschiedenen Berechtigungen reagiert werden soll. Wenn es darum geht einen gesamten Controller für Unberechtigte zu sperren nutzt man hingegen:

 load_and_authorize_resource

oder bei einer einzelnen Controller-Methode z.B.:

 @rating = Rating.find(params[:id])
 authorize! :update, @rating

um abzufragen, ob das momentan ausgewählte Rating aktualisiert werden darf.

Wenn nun ein Zugriff auf eine Controller-Methode verweigert wird, wird eine CanCan::AccessDenied-Exception geworfen, welche man dann wie jede andere Exception fangen und weiter bearbeiten kann.

Beispiel eines Controllerzugriffs

Hier wird noch einmal beispielhaft der Zugriff auf einen Controller erläutert:

  1. Jemand fragt von seinem Browser aus eine Adresse an und wird zum entsprechenden Controller geroutet.
  2. Wenn der Nutzer nicht angemeldet ist, wird er direkt vom Devise gestoppt und zur Anmeldung weitergeleitet.
  3. Wenn er angemeldet ist, fragt der Controller bei der Ability-Klasse nach, ob der Nutzer die Berechtigung hat die Seite zu nutzen.
  4. Die Ability nutzt dann je nach Rolle verschiedene Sets von Berechtigungen.
  5. In diesen Sets sind Abgleiche mit dem Modell, ob ein Nutzer bestimmte Eigenschaften besitzt, enthalten.
  6. Je nachdem ob der Nutzer die gesuchten Eigenschaften erfüllt, gibt die Ability an den Controller eine true/false-Antwort zurück.
  7. Bei true erhält der Nutzer Zugriff auf den Controller und damit auf das verbundene View-Template, falls die Antwort false ist wird eine Exception geworfen, welche den Nutzer mit einem entsprechenden Hinweis auf eine vordefinierte andere Seite umleitet.

Spezifische Anfragen eines Controllers oder eines View-Templates mit „can?“ werden im Prinzip genauso behandelt; der einzige Unterschied ist, dass die Reaktion auf die Rückgabe andere Konsequenzen hat.


Page last modified on August 21, 2011, at 07:55 PM