本文件旨在描述 Subversion 1.6.x 系列。如果您使用的是其他版本的 Subversion,强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅与您的 Subversion 版本相符的文档版本。
在某个时候,您需要了解 Subversion 客户端如何与服务器通信。Subversion 的网络层是抽象的,这意味着无论 Subversion 客户端针对哪种类型的服务器运行,它们都表现出相同的通用行为。无论是与 Apache HTTP 服务器使用 HTTP 协议 (http://
) 通信,还是与 svnserve 使用自定义 Subversion 协议 (svn://
) 通信,基本网络模型都是一样的。在本节中,我们将解释该网络模型的基础知识,包括 Subversion 如何管理身份验证和授权问题。
Subversion 客户端大部分时间都用于管理工作副本。但是,当它需要从远程仓库获取信息时,它会发出网络请求,服务器会以相应的答案进行响应。网络协议的细节对用户隐藏——客户端尝试访问一个 URL,并且根据 URL 方案,使用特定协议与服务器进行通信(参见 名为“仓库地址”的部分)。
![]() |
提示 |
---|---|
运行 |
当服务器进程接收到客户端请求时,它通常会要求客户端进行身份验证。它向客户端发出身份验证挑战,客户端通过向服务器提供 凭据 来响应。身份验证完成后,服务器会以客户端请求的原始信息进行响应。请注意,此系统不同于 CVS 等系统,在 CVS 中,客户端会在发出请求之前预先提供凭据(““登录”)。在 Subversion 中,服务器在适当的时机通过向客户端发起挑战来““提取” 凭据,而不是客户端““推送” 凭据。这使得某些操作更加优雅。例如,如果服务器配置为允许世界上任何人都可以读取仓库,则当客户端尝试进行 svn checkout 时,服务器永远不会发出身份验证挑战。
如果客户端发出的特定网络请求导致仓库中创建了新的版本(例如,svn commit),Subversion 会将与这些请求关联的已验证用户名用作该版本的作者。也就是说,已验证用户的名称存储为新版本的 svn:author
属性的值(参见 名为“Subversion 属性”的部分)。如果客户端未进行身份验证(即,服务器从未发出身份验证挑战),则该版本的 svn:author
属性为空。
许多 Subversion 服务器都配置为要求身份验证。有时允许匿名读取操作,而写入操作则必须经过身份验证。在其他情况下,读取和写入都需要身份验证。Subversion 的不同服务器选项支持不同的身份验证协议,但从用户的角度来看,身份验证通常归结为用户名和密码。Subversion 客户端提供多种不同的方法来检索和存储用户的身份验证凭据,从交互式提示输入用户名和密码,到加密和非加密的磁盘数据缓存。
注重安全的读者会立即怀疑这里有值得关注的原因。““在磁盘上缓存密码?太糟糕了!你永远不应该这样做!”” 别担心,没有那么糟糕。以下部分将讨论 Subversion 使用的各种类型的凭据缓存,何时使用它们以及如何在整体上或部分禁用该功能。
Subversion 提供了解决方案,可以消除用户被迫一遍又一遍地输入用户名和密码带来的困扰。默认情况下,每当命令行客户端成功响应服务器的身份验证挑战时,凭据就会被缓存在磁盘上,并根据服务器的主机名、端口和身份验证域的组合进行键值映射。将来会自动查询此缓存,从而避免用户重新输入身份验证凭据。如果缓存中似乎没有合适的凭据,或者缓存的凭据最终未能通过身份验证,则客户端默认情况下会回退到提示用户输入所需信息。
Subversion 开发人员认识到,磁盘上的身份验证凭据缓存可能会带来安全风险。为了抵消这种风险,Subversion 会使用操作系统和环境提供的可用机制,以尽量减少泄露此信息的风险。
在 Windows 上,Subversion 客户端将密码存储在 %APPDATA%/Subversion/auth/
目录中。在 Windows 2000 及更高版本上,使用标准 Windows 加密服务对磁盘上的密码进行加密。由于加密密钥由 Windows 管理,并与用户的登录凭据绑定,因此只有用户可以解密缓存的密码。(请注意,如果管理员重置了用户的 Windows 帐户密码,所有缓存的密码都将无法解密。Subversion 客户端将表现得好像它们不存在,并在需要时提示输入密码。)
类似地,在 Mac OS X 上,Subversion 客户端将所有仓库密码存储在登录密钥环中(由 Keychain 服务管理),该密钥环受用户帐户密码保护。用户偏好设置可以强制执行额外的策略,例如要求用户在每次使用 Subversion 密码时都输入其帐户密码。
对于其他类 Unix 操作系统,没有单一的标准““密钥环” 服务。但是,Subversion 客户端知道如何使用““GNOME Keyring” 和““KDE Wallet” 服务安全地存储密码。此外,在将未加密的密码存储在 ~/.subversion/auth/
缓存区域之前,Subversion 客户端会询问用户是否允许这样做。请注意,auth/
缓存区域仍然受到权限保护,因此只有用户(所有者)可以读取其中的数据,而不能让全世界访问。只要用户没有直接访问主目录的存储介质或备份,操作系统自身的权限就可以保护密码免受同一系统上的其他非管理员用户访问。
当然,对于那些真正偏执的人来说,这些机制都无法达到完美的标准。因此,对于那些愿意为了终极安全而牺牲便利性的人来说,Subversion 提供了多种方法来完全禁用其凭据缓存系统。
当您执行需要您进行身份验证的 Subversion 操作时,Subversion 默认情况下会尝试将您的身份验证凭据以加密形式缓存在磁盘上。在某些系统上,Subversion 可能无法加密您的身份验证数据。在这种情况下,Subversion 会询问您是否要将凭据以明文形式缓存在磁盘上
$ svn checkout https://host.example.com:443/svn/private-repo ----------------------------------------------------------------------- ATTENTION! Your password for authentication realm: <https://host.example.com:443> Subversion Repository can only be stored to disk unencrypted! You are advised to configure your system so that Subversion can store passwords encrypted, if possible. See the documentation for details. You can avoid future appearances of this warning by setting the value of the 'store-plaintext-passwords' option to either 'yes' or 'no' in '/tmp/servers'. ----------------------------------------------------------------------- Store password unencrypted (yes/no)?
如果您希望在以后的操作中无需不断重新输入密码,您可以在此提示中回答 yes
。如果您担心以明文形式缓存 Subversion 密码,并且不想被反复询问,您可以在永久或针对每个服务器分别禁用明文密码缓存。
![]() |
警告 |
---|---|
在考虑如何使用 Subversion 的密码缓存系统时,您需要查阅客户端计算机上实施的任何管理策略——许多公司对员工身份验证凭据的存储方式有严格的规定。 |
要永久禁用明文密码缓存,请在本地机器上的 servers
配置文件中的 [global]
部分添加一行 store-plaintext-passwords = no
。要为特定服务器禁用明文密码缓存,请在 servers
配置文件中的相应组部分使用相同的设置。(参见 名为“配置选项”的部分,位于 第 7 章,自定义您的 Subversion 体验 中。)
要完全禁用任何单个 Subversion 命令行操作的密码缓存,请将 --no-auth-cache
选项传递给该命令行。要永久禁用所有缓存,请将 store-passwords = no
添加到本地机器上的 Subversion 配置文件。
有时用户需要从磁盘缓存中删除特定凭据。为此,您需要导航到 auth/
区域并手动删除相应的缓存文件。凭据缓存在单独的文件中;如果您查看每个文件内部,您会看到键和值。svn:realmstring
键描述了该文件关联的特定服务器域
$ ls ~/.subversion/auth/svn.simple/ 5671adf2865e267db74f09ba6f872c28 3893ed123b39500bca8a0b382839198e 5c3c22968347b390f349ff340196ed39 $ cat ~/.subversion/auth/svn.simple/5671adf2865e267db74f09ba6f872c28 K 8 username V 3 joe K 8 password V 4 blah K 15 svn:realmstring V 45 <https://svn.domain.com:443> Joe's repository END
找到合适的缓存文件后,只需将其删除。
所有 Subversion 命令行操作都接受 --username
和 --password
选项,这些选项允许您分别指定用户名和密码,这样 Subversion 就不会被迫提示您输入这些信息。如果您需要从脚本中调用 Subversion 并且不能依赖 Subversion 能够为您找到有效的缓存凭据,这将特别方便。当 Subversion 已经为您缓存了身份验证凭据,但您知道这些凭据不是您想要使用的凭据时,这些选项也很有用。也许多个系统用户共享一个系统登录名,但每个用户都有不同的 Subversion 身份。如果您希望 Subversion 只使用提供的用户名,但仍然提示您输入该用户名的密码,则可以省略此对中的 --password
选项。
关于 svn 的身份验证行为,尤其是关于 --username
和 --password
选项,最后再补充说明一下。许多客户端子命令都接受这些选项,但重要的是要理解,使用这些选项 并不 会自动将凭据发送到服务器。如前所述,服务器在认为必要时会从客户端 “拉取” 凭据;客户端无法 “推送” 凭据。如果将用户名和/或密码作为选项传递,只有在服务器请求时才会将它们提供给服务器。这些选项通常用于以与 Subversion 默认选择的用户名不同的用户身份进行身份验证(例如,您的系统登录名),或者在尝试避免交互式提示时使用(例如,从脚本调用 svn 时)。
![]() |
注意 |
---|---|
一个常见的错误是错误地配置服务器,使其永远不会发出身份验证挑战。当用户向客户端传递 |
以下是一个总结,描述了 Subversion 客户端在收到身份验证挑战时如何运行。
首先,客户端会检查用户是否在命令行选项中指定了任何凭据(--username
和/或 --password
)。如果是,则客户端将尝试使用这些凭据对服务器进行身份验证。
如果没有提供命令行凭据,或者提供的凭据无效,则客户端会在运行时配置的 auth/
区域中查找服务器的主机名、端口和域,以查看是否已缓存相应的凭据。如果是,则会尝试使用这些凭据进行身份验证。
最后,如果之前的机制未能成功地对用户进行身份验证,则客户端将通过交互式方式提示用户提供有效的凭据(除非通过 --non-interactive
选项或其特定于客户端的等效选项指示不要这样做)。
如果客户端通过任何这些方法成功地进行了身份验证,它将尝试将凭据缓存到磁盘上(除非用户已禁用此行为,如前所述)。