在某些情況下,你需要理解Subversion客戶端如何與伺服器通訊。Subversion網路層是抽像的,意味著Subversion客戶端不管其操作的對象都會使用相同的行為方式,不管是使用HTTP協議(http://)與Apache HTTP伺服器通訊或是使用自行定義Subversion協議(svn://)與svnserve通訊,基本的網路模型是相同的。在本小節,我們要解釋網路模型基礎,包括Subversion如何管理認證和授權訊息。
Subversion客戶端花費大量的時間來管理工作副本,當它需要遠程版本庫的訊息,它會做一個網路請求,然後伺服器給一個恰當的回答,具體的網路協議細節對用戶不可見,客戶端嘗試去訪問一個URL,根據URL模式的不同,會使用特定的協議與伺服器聯繫(見版本庫的 URL)。
用戶可以運行svn --version來查看客戶端可以使用的URL模式和協議。
當伺服器處理一個客戶端請求,它通常會要求客戶端確定它自己的身份,它會發出一個認證請求給客戶端,而客戶端通過提供憑證給伺服器作為響應,一旦認證結束,伺服器會響應客戶端最初請求的訊息。注意這個系統與CVS之類的系統不一樣,它們會在請求之前,預先提供憑證(「logs in」)給伺服器,在Subversion裡,伺服器通過請求客戶端適時地「拖入」憑證,而不是客戶端「推」出,這使得這種操作更加的優雅。例如,如果一個伺服器設定為世界上的任何人都可以讀取版本庫,在客戶使用svn checkout時,伺服器永遠不會發起一個認證請求。
如果客戶端的請求會在版本庫建立新的修訂版本(例如svn commit),Subversion就會使用認證過的用戶名作為此次提交的作者。也就是說經過認證的用戶名作為svn:author屬性的值保存到新的修訂本裡(見「Subversion屬性」一節)。如果客戶端沒有經過認證(換句話說,伺服器沒有發起過認證請求),這時修訂本的svn:author的值是空的。
許多伺服器設定為每次請求要求認證,對被強制每次輸入用戶名密碼,許多用戶會感到很討厭。幸運的是,Subversion客戶端對此有一個修補—存在一個在磁碟上保存認證憑證快取的系統,預設情況下,當一個指令列客戶端成功的響應了伺服器的認證請求,它會保存一個認證文件到用戶的私有運行設定區(類Unix系統下會在~/.subversion/auth/,Windows下在%APPDATA%/Subversion/auth/,運行設定系統在「運行設定區」一節會有更多細節描述)。成功的憑證會快取在磁碟,以主機名、埠號和認證域的組合作為唯一性區別。
當客戶端接收到一個認證請求,它會首先查找用戶磁碟中的認證憑證快取,如果沒有發現,或者是快取的憑證認證失敗,客戶端會提示用戶提供需要的訊息。
十分關心安全的人們一定會想「把密碼快取在磁碟?太可怕了,永遠不要這樣做!」
Subversion開發者認識到這種關注的正確性,所以Subversion使用操作系統和環境提供的機制來減少洩露這些訊息的風險,下面是在大多數平台上這種含義的列表:
在Windows 2000或更新的系統上,Subversion客戶端使用標準Windows加密服務來加密磁碟上的密碼。因為加密密鑰是Windows管理的,與用戶的登陸憑證相關,只有用戶可以解密密碼。(注意:如果用戶的Windows賬戶密碼被管理員重置,所有的快取密碼就不可以解密了,此時Subversion客戶端就會當它們根本不存在,在需要時繼續詢問密碼。)
類似的,在Mac OS X,Subversion客戶端在登陸keyring(使用Keychain管理)保存了所有的版本庫密碼,使用戶用帳號密碼保護。用戶選擇的設定可以強加額外的政策,例如在需要用戶密碼時要求輸入用戶帳號密碼。
對於其他類Unix系統,沒有標準的加密服務。然而auth/快取區只有用戶(擁有者)可以訪問,而不是全世界都可以,操作系統的訪問許可可以保護密碼文件。
當然,對於真正的妄想狂,沒有任何機制是完美的。這類人希望用無限的安全來犧牲便利性,Subversion提供了各種方法來完全關閉憑證快取。
你可以關閉憑證快取,只需要一個簡單的命令,使用參數--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文件,只需要把store-auth-creds設定為no,這樣在影響的主機上的Subversion操作就不會有憑證快取在磁碟。通過修改系統級的運行設定區,這個功能也會影響到本機的所有用戶(詳細內容見「設定區部署」一節)。
[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
一旦你定位了正確的快取文件,只需要刪除它。
svn--username--password--username--passwordsvn)
這裡是Subversion客戶端在收到認證請求的時候的行為方式最終總結:
首先,檢查用戶是否通過命令選項(--username和/或--password)指定了任何憑證訊息,如果沒有,或者這些選項沒有認證成功,然後
查找運行中的auth/區域保存的伺服器名,埠號和認證域訊息,來確定用戶是否已經有了恰當的認證快取,如果沒有,或者快取憑證認證失敗,然後
最終,客戶端返回要求用戶(除非使用--non-interactive選項或客戶端對等的方式)。
如果客戶端通過以上的任何一種方式成功認證,它會嘗試在磁碟快取憑證(除非用戶已經關閉了這種行為方式,在前面提到過。)