本文件旨在介绍 Subversion 1.4。如果您使用的是更新版本的 Subversion,我们强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅适合您 Subversion 版本的书籍。

基于路径的授权

Apache 和 svnserve 都能够授予(或拒绝)用户的权限。通常,这在整个仓库中进行:用户可以读取(或不能读取)仓库,用户可以写入(或不能写入)仓库。但是,也可以定义更细粒度的访问规则。一组用户可能被允许写入仓库中的某个特定目录,而其他用户则不被允许;另一个目录可能只有少数特定用户可以读取。

这两个服务器都使用一个通用的文件格式来描述这些基于路径的访问规则。对于 Apache,需要加载 mod_authz_svn 模块,然后添加 AuthzSVNAccessFile 指令(在 httpd.conf 文件中),该指令指向您自己的规则文件。(有关完整说明,请参见 名为“按目录访问控制”的部分。)如果您使用的是 svnserve,则需要将 authz-db 变量(在 svnserve.conf 中)指向您的规则文件。

一旦您的服务器知道在哪里找到您的规则文件,就可以开始定义规则了。

文件的语法与 svnserve.conf 和运行时配置文件中使用的熟悉语法相同。以井号 (#) 开头的行会被忽略。在最简单的形式中,每个部分都会命名仓库中一个路径,并且经过身份验证的用户名是每个部分内的选项名称。每个选项的值描述了用户对仓库路径的访问级别:r(只读)或 rw(读写)。如果用户根本没有被提及,则不允许访问。

更准确地说:部分名称的值可以是 [repos-name:path] 形式或 [path] 形式。如果您使用的是 SVNParentPath 指令,那么在部分中指定仓库名称很重要。如果您省略了它们,那么像 [/some/dir] 这样的部分将匹配每个仓库中的 /some/dir 路径。但是,如果您使用的是 SVNPath 指令,那么在部分中只定义路径就可以了——毕竟只有一个仓库。

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

在本例中,用户 harrycalc 仓库中的 /branches/calc/bug-142 目录拥有完全的读写权限,但用户 sally 只有只读权限。其他用户被禁止访问此目录。

当然,权限是从父目录继承到子目录的。这意味着我们可以为 Sally 指定一个具有不同访问策略的子目录

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

# give sally write access only to the 'testing' subdir
[calc:/branches/calc/bug-142/testing]
sally = rw

现在 Sally 可以写入分支的 testing 子目录,但她仍然只能读取其他部分。与此同时,Harry 继续对整个分支拥有完整的读写权限。

还可以通过继承规则显式地拒绝某人的权限,方法是将用户名变量设置为 null

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

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

在本例中,Harry 对整个 bug-142 树拥有读写权限,但对其中的 secret 子目录没有任何访问权限。

要记住的是,最具体的路径总是首先匹配。服务器会尝试匹配路径本身,然后是路径的父级,然后是父级的父级,依此类推。最终效果是,在访问文件中提及特定路径将始终覆盖从父目录继承的任何权限。

默认情况下,任何人都没有仓库的任何访问权限。这意味着,如果您从一个空文件开始,您可能希望至少授予所有用户对仓库根目录的读取权限。您可以通过使用星号变量 (*) 来实现,它的含义是“所有用户

[/]
* = r

这是一个常见的设置;请注意,部分名称中没有提及仓库名称。这使得所有仓库对所有用户都可读。一旦所有用户都拥有对仓库的读取权限,您就可以对特定仓库中特定子目录的某些用户授予显式的 rw 权限。

星号变量 (*) 在这里也值得特别提及:它是唯一匹配匿名用户的模式。如果您已配置服务器块以允许匿名和经过身份验证的访问混合使用,则所有用户最初都以匿名方式访问。服务器会查找为正在访问的路径定义的 * 值;如果找不到,它将要求客户端进行真正的身份验证。

访问文件还允许您定义整个用户组,这与 Unix /etc/group 文件非常相似

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

组可以像用户一样被授予访问控制权限。通过前缀“at” (@) 来区分它们

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

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

组还可以被定义为包含其他组

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


[48] 本书中的一个常见主题!