本文档尚在编写中,内容可能会发生很大变化,可能无法准确描述任何已发布的 Apache™ Subversion® 软件版本。将此页面添加为书签或推荐给其他人可能不是明智之举。请访问 https://svnbook.subversion.org.cn/ 获取本书的稳定版本。
在某个时刻,您将需要了解 Subversion 客户端如何与其服务器通信。Subversion 的网络层是抽象的,这意味着 Subversion 客户端无论针对哪种服务器运行,都会表现出相同的通用行为。无论是使用 HTTP 协议 (http://
) 与 Apache HTTP 服务器通信,还是使用自定义 Subversion 协议 (svn://
) 与 svnserve 通信,基本网络模型都是相同的。在本节中,我们将解释该网络模型的基础知识,包括 Subversion 如何管理身份验证和授权事宜。
Subversion 客户端大部分时间都在管理工作副本。但是,当它需要从远程存储库获取信息时,它会发出网络请求,服务器会以适当的答案进行响应。网络协议的细节对用户隐藏了——客户端尝试访问一个 URL,并且根据 URL 方案,使用特定的协议与服务器联系(参见 名为“Addressing the Repository”的部分)。
提示 | |
---|---|
运行 |
当服务器进程接收到客户端请求时,它通常要求客户端进行身份验证。它向客户端发出身份验证质询,客户端通过向服务器提供 凭据 来响应。身份验证完成后,服务器会以客户端请求的原始信息进行响应。请注意,此系统与 CVS 等系统不同,在 CVS 中,客户端会预先向服务器提供凭据(“登录”),然后才能发出请求。在 Subversion 中,服务器在适当的时刻通过对客户端发出质询来 “拉取” 凭据,而不是客户端 “推送” 它们。这使得某些操作更加优雅。例如,如果服务器配置为允许世界上任何人都读取存储库,那么当客户端尝试 svn checkout 时,服务器将永远不会发出身份验证质询。
如果客户端发出的特定网络请求导致存储库中创建了一个新的修订版(例如,svn commit),Subversion 会将与这些请求关联的已验证用户名用作修订版的作者。也就是说,已验证用户的姓名将存储为新修订版上的 svn:author
属性的值(参见 名为“Subversion's Reserved Properties”的部分)。如果客户端未经身份验证(即,如果服务器从未发出身份验证质询),则修订版的 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” 和 “GnuPG Agent” 服务安全地存储密码。此外,在将未加密的密码存储在 ~/.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
配置文件中的相应组部分使用相同的设置。(参见 名为“Runtime Configuration Options”的部分,位于 第 7 章,Customizing Your Subversion Experience 中以了解详细信息。)
要完全禁用任何单个 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
选项或其特定于客户端的等效项指示不要这样做)。
如果客户端通过任何这些方法成功地进行了身份验证,它将尝试将凭据缓存到磁盘上(除非用户已禁用此行为,如前所述)。