本文档旨在描述 Apache™ Subversion® 的 1.7.x 系列。如果您运行的是其他版本的 Subversion,强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅适合您 Subversion 版本的文档。
在某些情况下,您需要了解 Subversion 客户端如何与其服务器通信。Subversion 的网络层是抽象的,这意味着 Subversion 客户端无论针对哪种服务器运行,都表现出相同的通用行为。无论是使用 Apache HTTP Server 协议 (http://
) 还是使用自定义 Subversion 协议 (svn://
) 与 svnserve 通信,基本的网络模型都是一样的。在本节中,我们将解释该网络模型的基础知识,包括 Subversion 如何管理身份验证和授权事宜。
Subversion 客户端大部分时间都在管理工作副本。但是,当它需要从远程存储库获取信息时,它会发出网络请求,服务器会以适当的答案进行响应。网络协议的详细信息对用户隐藏——客户端尝试访问 URL,并根据 URL 方案使用特定协议与服务器联系(参见 Addressing the Repository)。
![]() |
提示 |
---|---|
运行 |
当服务器进程接收到客户端请求时,它通常要求客户端进行身份验证。它向客户端发出身份验证挑战,客户端通过向服务器提供凭据来响应。身份验证完成后,服务器将返回客户端请求的原始信息。请注意,此系统不同于 CVS 等系统,在 CVS 中,客户端会在发出任何请求之前预先向服务器提供凭据(“登录”)。在 Subversion 中,服务器通过在适当的时候向客户端发出挑战来“拉取”凭据,而不是客户端“推送”凭据。这使得某些操作更加优雅。例如,如果服务器配置为允许世界上任何人都可以读取存储库,那么当客户端尝试svn checkout时,服务器永远不会发出身份验证挑战。
如果客户端发出的特定网络请求导致存储库中创建了新的修订版(例如,svn commit),Subversion 将使用与这些请求关联的已验证用户名作为修订版的作者。也就是说,已验证用户的名称将存储为新修订版上svn:author
属性的值(请参阅名为“Subversion 属性”的部分,位于第 9 章,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 客户端将所有存储库密码存储在登录钥匙串中(由钥匙串服务管理),该钥匙串受用户帐户密码保护。用户偏好设置可以实施额外的策略,例如要求用户在每次使用 Subversion 密码时输入其帐户密码。
对于其他类 Unix 操作系统,没有单一的标准 “密钥链” 服务。但是,Subversion 客户端知道如何使用 “GNOME 密钥环” 和 “KDE 钱包” 服务安全地存储密码。此外,在将未加密的密码存储在 ~/.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
选项。要永久禁用完全缓存,请在本地机器的 Subversion 配置文件中添加一行 store-passwords = no
。
有时用户可能希望从磁盘缓存中删除特定凭据。为此,您需要导航到 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
选项或其特定于客户端的等效项指示不要这样做)。
如果客户端通过任何这些方法成功地进行了身份验证,它将尝试将凭据缓存到磁盘上(除非用户已禁用此行为,如前所述)。