本节是对Subversion客户机和服务器如何交互的一般性讨论,无论你在使用什么网络实现。在读完后,你将对服务器如何运转和 客户端可配置的不同响应方式有一个很好的理解。
Subversion客户端大部分时间用于管理工作副本。但是当它需要来自资料库的信息时,它发起一个网络请求,服务器回应以合适的答案。 网络协议的细节对用户隐藏了;客户端尝试访问一个URL,根据URL模式来使用特定的协议来联系服务器(参见 资料库URL)。用户可以运行 svn --version 来查看客户端懂得使用哪些URL模式和协议。
当服务器进程接收到一个客户端请求时,它通常需要客户端自身的标识。它向客户端发出一个认证质询,客户端回应给服务器认证凭证(credentials)。 一旦认证完成,服务器将回应给客户端它原本要求的信息。注意这个系统和CVS这样的系统不同,那些系统里客户端在发起请求前就需要 提前提供凭证(“登录log in”)。在Subversion里,服务器通过在适当的时候向客户端发起要求来“拉入”凭证, 而不是靠客户端来“推入”他们。这使得某些操作更加优雅。例如,如果服务器被配置为允许世界上的任何人来读资料库, 那么在客户端企图 svn checkout时,这服务器将永不会提出认证要求。
如果客户端发起的网络请求要往资料库里写新数据(比如,svn commit),那么一个新修订版树被创建。如果客户端请求被
认证了,那么认证的用户名被存储为这个新修订版的svn:author属性的值(参见“未版本化的属性”一节)。如果客户端没有认证(换句话说,服务器从来没有要求认证),那么修订版的svn:author属性是空的。
[18]
很多服务器被配置为每个请求都需要认证。这对用户会成为很大的烦恼:他们被迫一次又一次的敲入他们的密码。
值得高兴的是,Subversion客户端对这问题有个补救:一个内建在磁盘上缓存认证凭证的系统。缺省情况下,一旦命令行客户端成功的在一个服务器
认证了自己,它将在用户的私有运行时配置区域——在Unix类系统上是~/.subversion/auth/,或在Windows上的
%APPDATA%/Subversion/auth/——保存这些凭证(运行时区域在???更详细的谈到)。成功的凭证被缓存到磁盘上,以主机名,端口和认证区域的结合作为键。
当客户端接到认证要求时,它首先在磁盘缓存里寻找合适的凭证,如果缓存的凭证认证失败,那么客户端就提示用户输入这些信息。
安全狂热的人们可能心中盘算,“在磁盘上缓存密码?太可怕了!你永远不应该这么做!”但是请保持镇静。首先,
auth/缓存区域是有权限保护的,因此只有这个用户(所有者)才能从这里读数据,在不是整个世界。
如果对你来说这还不够安全,你可以禁止证书缓存。要在某个命令上禁止缓存,可以传递--no-auth-cache选项给它:
$ svn commit -F log_msg.txt --no-auth-cache Authentication realm: <svn://host.example.com:3690> example realm Username: joe Password for 'joe': Adding newfile Transmitting file data . Committed revision 2324. # password was not cached, so a second commit still prompts us $ svn delete newfile $ svn commit -F new_msg.txt Authentication realm: <svn://host.example.com:3690> example realm Username: joe [...]
或者,如果你想永久禁止证书缓存,那么你可以编辑你的运行时 config文件(位于auth/
目录里面)。只要把store-auth-creds设为no,那么证书文件将不再被缓存。
[auth] store-auth-creds = 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
一旦你找到了正确的缓存文件,删除它就可以了。
关于客户端认证行为的最后一点说明:需要稍微解释一下--username和--password选项。很多客户端
子命令接受这些选项;但是重要的是要理解使用这些选项不会自动的发送凭证到服务器。如同在前面讨论过的,
服务器在它认为需要的时候从客户端“拉”证书;客户端不能随意的“推”它们。如果用户和密码作为参数被传入,
它们将只在服务器要求的时候被呈现给它。
[19]
通常,这些选项在这些情况下使用:
用户想以不同于她的系统登陆名的用户来认证,或者
一个脚本想不用缓存的证书来认证。
这里是一个最终的总结,描述了Subversion客户端在收到认证要求时的行为:
检查用户是否在命令行选项中通过--username和/或--password指定了任何认证信息。如果没有,
或者如果这些选项没能通过认证,那么
检查在运行时auth/区域中的服务器领域,来查看是否用户已经有缓存的适当的凭证。如果没有,或如果缓存的
凭证没有通过认证,那么
最后再提示用户输入。
如果客户端用上列任何办法认证成功,那么它将尝试在磁盘上缓存凭证(如果用户没有如前面提到的那样禁止这种行为的话)。