Dieser Text befindet sich gegenwärtig in Bearbeitung, unterliegt ständigen Änderungen und kann dadurch nicht stets akkurat irgendeine freigegebene Version der Software Apache™ Subversion® beschreiben. Das Speichern dieser Seite als Lesezeichen oder andere auf diese Seite zu verweisen, ist keine so gute Idee. Besuchen Sie http://www.svnbook.com/, um stabile Versionen dieses Buchs zu erhalten.

Pfad-basierte Autorisierung

Sowohl Apache als auch svnserve können Anwendern Zugriffsrechte gewähren (oder verweigern). Normalerweise geschieht das für das gesamte Projektarchiv: ein Anwender darf das Projektarchiv lesen (oder auch nicht) und ein Anwender darf in das Projektarchiv schreiben (oder auch nicht).

Es ist jedoch ebenfalls möglich, feiner abgestufte Zugriffsregeln zu definieren. Ein Anwender dürfte nur in ein bestimmtes Verzeichnis des Projektarchivs schreiben, aber in kein anderes; ein weiteres Verzeichnis könnte bis auf wenige besondere Personen für niemanden lesbar sein. Es ist sogar möglich, den Zugriff dateiabhängig einzurichten.

Beide Subversion-Server verwenden ein gemeinsames Dateiformat, um diese pfad-basierten Zugriffsregeln zu beschreiben. Im diesem Abschnitt erklären wir sowohl dieses Dateiformat als auch, wie Ihr Subversion-Server konfiguriert werden muss, damit er für pfad-basierte Autorisierung benutzt werden kann.

Loslegen mit pfad-basierter Zugriffskontrolle

Subversion bietet pfad-basierte Zugriffskontrolle in Apache über das Modul mod_authz_svn an, das mit der Direktive LoadModule in httpd.conf geladen werden muss, genau so, wie auch mod_dav_svn selbst geladen wird. Um die Verwendung dieses Moduls für Ihre Projektarchive zu ermöglichen, müssen Sie die Direktive AuthzSVNAccessFile hinzufügen (auch in der Datei httpd.conf), die auf Ihre eigene Datei mit Zugriffsregeln zeigt. (Für eine vollständige Erklärung, siehe „Verzeichnisweise Zugriffskontrolle“.)

Um pfad-basierte Autorisierung in svnserve zu konfigurieren, müssen Sie einfach die Konfigurationsvariable authz-db (in Ihrer Datei svnserve.confe) auf Ihre Datei mit den Zugriffsregeln zeigen lassen.

Sobald Ihr Server weiß, wo sich Ihre Zugriffsdatei befindet, ist es an der Zeit, die Regeln zu definieren.

Die Syntax der Subversion Zugriffs-Datei ist dieselbe wie bei svnserve.conf und den Laufzeit-Konfigurationsdateien. Zeilen, die mit einer Raute (#) beginnen, werden ignoriert. In der einfachsten Form benennt jeder Abschnitt einen versionierten Pfad und, optional, das Projektarchiv in dem dieser Pfad sich befindet. Mit anderen Worten, außer bei ein paar reservierten Abschnitten, haben Abschnittsnamen eins von zwei möglichen Formaten: entweder [projektarchiv-name:pfad] oder [pfad]. Authentifizierten Anwendernamen sind die Optionsnamen innerhalb jedes Abschnitts, und der Wert einer Option beschreibt das Zugriffsrecht des Anwenders auf den Pfad im Projektarchiv, entweder r (nur lesend) oder rw (lesend und schreibend). Wird der Anwender gar nicht erwähnt, ist kein Zugriff erlaubt.

[Anmerkung] Anmerkung

Die in Zugriffs-Dateien verwendeten Pfade müssen im internen Stil von Subversion angegeben werden, was meist nur bedeutet, dass sie in UTF-8 kodiert sind und Schrägstriche (/) als Verzeichnistrenner verwenden (sogar auf Windows-Systemen). Beachten Sie ebenfalls, dass diese Pfade keinerlei Maskierung einsetzen (etwa URI-Kodierung); Leerzeichen in Dateinamen sollen in Abschnittsnamen von Zugriffsdateien exakt wiedergegeben werden (z.B., [repos-name:path with spaces]),

Hier ist ein einfaches Beispiel eines Teils einer Zugriffskonfiguration, die für den Pfad /branches/calc/bug-142 (und allen seiner Kinder) im Projektarchiv calc Sally Lesezugriff und Harry Schreib- und Lesezugriff gewährt:

[calc:/branches/calc/bug-142]
harry = rw
sally = r
[Warnung] Warnung

Vor Version 1.7 hat Subversion bei Namen und Pfaden von Projektarchiven nicht die Groß- oder Kleinschreibung beachtet, da sie vor dem Vergleich mit dem Inhalt der Zugriffsdatei in Kleinbuchstaben umgewandelt wurden. Nun werden Vergleiche unter Berücksichtigung der Groß- und Kleinschreibung vorgenommen. Falls Sie eine ältere Version auf Subversion 1.7 aktualisiert haben, sollten Sie Ihre Zugriffsdateien auf die korrekte Groß- und Kleinschreibung überprüfen.

Der vom Autorisierungs-Subsystem berechnete Name des Projektarchivs wird direkt von seinem Pfad abgeleitet. Es hängt von zwei Server-Optionen ab, wie das genau geschieht. mod_dav_svn verwendet lediglich den Basisnamen des Wurzel-URLs vom Projektarchiv[71], während svnserve den vollständigen, relativen Pfad vom Server-Wurzelverzeichnis (wie in der Befehlszeilen-Option --root (-r) angegeben) zum Projektarchiv verwendet.

[Warnung] Warnung

Die unterschiedliche Art, auf die mod_dav_svn und svnserve den Namen eines Projektarchivs zu ermitteln versuchen, können zu Problemen führen, falls ein Projektarchiv von beiden Servern gleichzeitig bedient werden soll. Natürlich würde es ein Administrator bevorzugen, für die Konfiguration beider Server nur eine gemeinsame Zugriffsdatei zu verwenden. Damit das allerdings funktioniert, müssen Sie sicherstellen, dass der Teil mit dem Namen des Projektarchivs in den Abschnittsnamen der Datei kompatibel zu dem ist, was jeder einzelne Server für den Namen des Projektarchivs erachtet – beispielsweise, indem das Wurzelverzeichnis von svnserve so definiert wird, dass es gleich dem SVNParentPath von mod_dav_svn ist, oder indem eine unterschiedliche Zugriffsdatei für jedes Projektarchiv verwendet wird, so dass die Abschnittsnamen sich überhaupt nicht auf ein Projektarchiv beziehen müssen.

Falls Sie die Direktive SVNParentPath verwenden, ist es wichtig, die Namen der Projektarchive in den Abschnitten anzugeben. Falls Sie sie weglassen, wird ein Abschnitt wie etwa [/some/dir] auf den Pfad /some/dir jedes Projektarchivs zutreffen. Falls Sie jedoch die Direktive SVNPath verwenden, ist es in Ordnung, in den Abschnitten nur Pfade anzugeben, da es ja schließlich nur ein einziges Projektarchiv gibt.

Berechtigungen werden vom Elternverzeichnis ererbt. Das bedeutet, dass wir ein Unterverzeichnis mit unterschiedlichen Berechtigungen für Sally angeben können. Machen wir mit unserem vorigen Beispiel weiter und geben Sally Schreibzugriff auf ein Kindverzeichnis des Zweigs, auf dass Sie sonst nur lesend zugreifen dürfte:

[calc:/branches/calc/bug-142]
harry = rw
sally = r

# Sally bekommt nur für das Unterverzeichnis 'testing' Schreibrecht
[calc:/branches/calc/bug-142/testing]
sally = rw

Nun kann Sally im Verzeichnis testing des Zweigs zwar schreiben, an anderen Stellen allerdings immer noch nur lesen. Andererseits besitzt Harry weiterhin vollständigen Lese- und Schreibzugriff auf den gesamten Zweig.

Es ist ebenfalls möglich, einer Person über die Vererbungsregeln explizit Berechtigungen zu entziehen, indem die Variable mit dem Anwendernamen auf den leeren Wert gesetzt wird:

[calc:/branches/calc/bug-142]
harry = rw
sally = r

[calc:/branches/calc/bug-142/secret]
harry =

In diesem Beispiel hat Harry Lese- und Schreibzugriff auf den gesamten Baum bug-142, jedoch überhaupt keinen Zugriff auf das darin befindliche Unterverzeichnis secret.

[Tipp] Tipp

Man muss sich nur merken, dass stets zuerst der am genauesten angegebene Pfad passt. Der Server versucht zunächst, den Pfad selbst abzugleichen, dann das Elternverzeichnis hiervon, dann dessen Elternverzeichnis usw. Unter dem Strich läuft es darauf hinaus, dass die Erwähnung eines bestimmten Pfades in der Zugriffsdatei stets die von Elternverzeichnissen ererbten Berechtigungen überdeckt.

Ähnlich haben Abschnitte, die den Namen eines Projektarchivs angeben, Vorrang vor denen ohne: falls sowohl [calc:/irgendein/pfad] als auch [/irgendein/pfad] vorkommen, wird für calc ersterer verwendet und letzterer ignoriert.

Standardmäßig hat niemand irgendeine Zugriffsberechtigung auf irgendein Projektarchiv. Das bedeutet, wenn mit einer leeren Datei begonnen wird, sollte mindestens für alle Anwender die Leseberechtigung für die Wurzeln der Projektarchive gewährt werden. Das kann mit der Stern-Variablen (*) erreicht werden, die für alle Anwender steht:

[/]
* = r

Dies ist eine verbreitete Einstellung. Beachten Sie, dass im Abschnittsnamen kein Projektarchiv erwähnt wird. Das führt dazu, dass alle Projektarchive für alle Anwender der Welt lesbar sind. Sobald alle Anwender Lesezugriff auf die Projektarchive haben, können Sie bestimmten Anwendern für ausgewählte Verzeichnisse bestimmter Projektarchive die Berechtigung rw geben.

Note that while all of the previous examples use directories, that's only because defining access rules on directories is the most common case. You may similarly restrict access on file paths, too.

[calendar:/projects/calendar/manager.ics]
harry = rw
sally = r

Zugriffskontroll-Gruppen

Die Zugriffsdatei erlaubt es Ihnen auch, ganze Anwendergruppen zu definieren, ähnlich der Unix-Datei /etc/group. Dafür erstellen Sie einen Abschnitt groups in Ihrer Zugriffsdatei und beschreiben in diesem Abschnitt anschließend Ihre Gruppen: jeder Name einer Variablen definiert den Namen der Gruppe, und deren Wert ist eine durch Kommata getrennte Liste aus den Anwendernamen der Gruppenmitglieder.

[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = harry, sally, joe, frank, jane

Gruppen können ebenso wie Anwendern Zugriffsberechtigungen erteilt werden. Sie werden von Anwendern durch einen At-Zeichen-Präfix (@) unterschieden:

[calc:/projects/calc]
@calc-developers = rw

[paint:/projects/paint]
jane = r
@paint-developers = rw

Ein weiterer wichtiger Punkt ist, dass Gruppenberechtigungen nicht durch die Berechtigungen individueller Anwender überschrieben werden. Vielmehr wird die Kombination aller passender Berechtigungen zugesichert. Im vorangehenden Beispiel ist Jane Mitglied der Gruppe paint-developers, die über Lese- und Schreibzugriff verfügt. Kombiniert mit der Regel jane = r ergibt das immer noch Lese- und Schreibzugriff für Jane. Zugriffsrechte für Gruppenmitglieder können allenfalls über die Gruppenberechtigungen hinaus erweitert werden. Die Einschränkung von Anwendern, die Gruppenmitglieder sind auf geringere Berechtigungen als deren Gruppenberechtigung ist nicht möglich.

Gruppen können auch definiert werden, indem sie andere Gruppen beinhalten:

[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = @calc-developers, @paint-developers

Anwendernamen-Aliase

Einige Authentifikationssysteme erwarten und verwenden relativ kurze Anwendernamen, wie wir sie hier bereits beschrieben haben: harry, sally, joe usw. Andere Authentifikationssysteme jedoch, wie solche, die LDAP oder SSL-Client-Zertifikate verwenden, könnten wesentlich komplexere Anwendernamen verwenden. So könnte beispielsweise Harrys Anwendername in einem durch LDAP geschützten System CN=Harold Hacker,OU=Engineers,DC=red-bean,DC=com lauten. Mit derartigen Anwendernamen könnte die Zugriffsdatei mit langen oder undurchsichtigen Anwendernamen zugemüllt werden, was auch leicht zu Tippfehlern führen kann.

Glücklicherweise führte Subversion 1.5 Anwendernamen-Aliase in die Syntax der Zugriffsdatei ein. Anwendernamen-Aliase ermöglichen das einmalige Eintippen korrekter, komplizierter Anwendernamen in einer Anweisung, die diesem ein einfacheres Alias zuteilt.

Anwendernamen-Aliase werden im speziellen Abschnitt aliases der Zugriffsdatei definiert, wobei jeder Variablenname in diesem Abschnitt ein Alias festlegt und dessen Wert der tatsächliche Subversion-Anwendername ist, dem dieser Alias zugeteilt wird.

[aliases]
harry = CN=Harold Hacker,OU=Engineers,DC=red-bean,DC=com
sally = CN=Sally Swatterbug,OU=Engineers,DC=red-bean,DC=com
joe = CN=Gerald I. Joseph,OU=Engineers,DC=red-bean,DC=com
…

Sobald Sie eine Menge an Aliasen definiert haben, können Sie sich an allen Stellen der Zugriffsdatei über die Aliase auf die Anwender beziehen, an denen Sie sonst die eigentlichen Anwendernamen benutzt hätten. Setzen Sie einfach ein kaufmännisches Und vor den Alias, um ihn von einem normalen Anwendernamen zu unterscheiden:

[groups]
calc-developers = &harry, &sally, &joe
paint-developers = &frank, &sally, &jane
everyone = @calc-developers, @paint-developers

Sie könnten sich auch dazu entscheiden, Aliase zu verwenden, falls sich die Anwendernamen Ihrer Anwender häufig ändern. In diesem Fall müssen Sie bei Änderungen der Anwendernamen lediglich die Aliastabelle aktualisieren anstatt eine globale Such- und Ersetzungsoperation über die gesamte Zugriffsdatei vornehmen zu müssen.

Fortgeschrittene Zugriffskontroll-Funktionen

Beginnend mit Subversion 1.5 unterstützt die Syntax der Zugriffsdatei einige magische Symbole, die Ihnen dabei helfen sollen, Regeln abhängig von der Authentifikationsklasse des Anwenders zu vergeben. Ein solches Symbol ist $authenticated. Verwenden Sie dieses Symbol dort, wo Sie ansonsten einen Anwendernamen, einen Alias oder einen Gruppennamen in Ihren Autorisierungsregeln angeben würden, um die Zugriffsrechte zu deklarieren, die ein Anwender erteilt bekommt, der sich schon einmal mit einem Anwendernamen anmeldet. Ähnlich wird das Symbol $anonymous verwendet, mit der Ausnahme, dass es auf jeden anwendbar ist, der sich nicht mit einem Anwendernamen authentifiziert hat.

[calendar:/projects/calendar]
$anonymous = r
$authenticated = rw

Ein weiteres praktisches Stück magischer Zugriffsdatei-Syntax ist die Verwendung der Tilde (~) als eine Ausschlussmarkierung. Wenn Sie in Ihren Autorisierungsregeln einem Anwendernamen, einem Alias, einen Gruppennamen oder einem Authentifikationsklassen-Symbol eine Tilde voranstellen, gilt diese Regel für Anwender, die nicht durch diese Regel erfasst werden. Obwohl es unnötigerweise etwas verwirrend erscheint, ist der folgende Block äquivalent zu dem aus dem vorangegangenen Beispiel:

[calendar:/projects/calendar]
~$authenticated = r
~$anonymous = rw

Ein weniger offensichtliches Beispiel könnte wie folgt aussehen:

[groups]
calc-developers = &harry, &sally, &joe
calc-owners = &hewlett, &packard
calc = @calc-developers, @calc-owners

# jeder calc-Teilnehmer hat Lese- und Schreibzugriff...
[calc:/projects/calc]
@calc = rw

# ...doch nur die Eigentümer dürfen Release-Tags erstellen und ändern.
[calc:/projects/calc/tags]
~@calc-owners = r

Einige Fallstricke bei der Zugriffskontrolle

Falls Sie Apache als Ihren Subversion-Server verwenden und bestimmte Unterverzeichnisse Ihres Projektarchivs für bestimmte Anwender unlesbar gemacht haben, müssen Sie über ein mögliches suboptimales Verhalten von svn checkout Bescheid wissen.

Abhängig von der vom Client verwendeten Bibliothek zur HTTP-Kommunikation, kann es sein, dass er verlangt, die kompletten Nutzdaten eines Checkouts oder einer Aktualisierung in einer einzigen (oft sehr umfangreichen) Antwort auf die Hauptanfrage des Checkouts/der Aktualisierung abzuliefern. Wenn das geschieht, ist diese Anfrage die einzige Gelegenheit, die Authentifikation des Anwenders einzufordern. Das hat einige merkwürdige Seiteneffekte. Wenn beispielsweise ein Unterverzeichnis des Projektarchivs nur für die Anwenderin Sally lesbar ist und der Anwender Harry ein Elternverzeichnis auscheckt, wird sein Client auf die initiale Aufforderung zur Authentifikation als Harry antworten. Während der Server die umfangreiche Antwort erzeugt, besteht keine Möglichkeit beim Erreichen des besonderen Verzeichnisses eine erneute Aufforderung zu senden; das Verzeichnis wird somit einfach übergangen, anstatt den Anwender im passenden Moment aufzufordern, sich als Sally zu authentifizieren.

Auf ähnliche Weise wird der komplette Checkout ohne Authentifikation vollzogen, falls das Wurzelverzeichnis des Projektarchivs anonym für jeden lesbar ist; auch hier werden nicht lesbare Verzeichnisse übergangen, anstatt zwischendurch zur Authentifikation aufzufordern.[72]



[70] Ein in diesem Buch häufiges Thema!

[71] Irgendein menschenlesbarer Name für ein Projektarchiv, der mit der Direktive SVNReposName von httpd.conf konfiguriert wurde, wird vom Autorisierungs-Subsystem ignoriert. Die Abschnitte in der Zugriffskontrolldatei müssen sich auf Projektarchive über deren Pfade beziehen, die für Server ,wie oben beschrieben, erkennbar sind.

[72] Mehr hierzu im Blog-Post Authz and Anon Authn Agony auf http://blogs.collab.net/subversion/2007/03/authz_and_anon_/.