網路模型

在某些情況下,你需要理解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客戶端在收到認證請求的時候的行為方式最終總結:

  1. 首先,檢查用戶是否通過命令選項(--username和/或--password)指定了任何憑證訊息,如果沒有,或者這些選項沒有認證成功,然後

  2. 查找運行中的auth/區域保存的伺服器名,埠號和認證域訊息,來確定用戶是否已經有了恰當的認證快取,如果沒有,或者快取憑證認證失敗,然後

  3. 最終,客戶端返回要求用戶(除非使用--non-interactive選項或客戶端對等的方式)。

如果客戶端通過以上的任何一種方式成功認證,它會嘗試在磁碟快取憑證(除非用戶已經關閉了這種行為方式,在前面提到過。)