文章目錄
- 1. 為什麼使用 Windows 驗證?
- 2. 為什麼不使用 Windows 驗證?
- 3. Windows 驗證機制
- 3.1 Basic 驗證
- 3.2 Digest 驗證
- 3.3 整合 Windows 驗證
- 3.3.1 NTLM 驗證
- 3.3.2 Kerberos 驗證簡介
如果只為一小部分已知使用者開發 Web 程式,且這些使用者都有 Windows 帳號,在這種情況下,Windows 驗證是一個適合的解決方案。它可以利用已有的使用者和使用者分組資訊進行系統驗證。
和表單驗證不同,Windows 驗證沒有在 ASP.NET 中內建。Windows 驗證將驗證的責任交給了 IIS。IIS 通過瀏覽器驗證 Windows 使用者帳號的憑證。如果使用者驗證成功,IIS 則允許這次網頁請求,並將使用者和角色資訊傳遞給 ASP.NET,這樣你的程式就可以用幾乎和表單驗證一樣的方式處理這些資訊。
1. 為什麼使用 Windows 驗證?
- 對於開發,幾乎不需要進行多少編程工作
- Windows 驗證允許 IIS 和瀏覽器處理驗證流程,你不需要建立登入頁面、檢查資料庫或編寫任何自訂代碼,Windows 已經提供了基本的使用者帳號功能,比如密碼到期,密碼鎖定和使用者分組。
- 允許使用已有的使用者進行登入
- 通常,使用 Windows 驗證時,使用者是和 Web 服務器相同的本網或者企業內部互連網絡的一部分。這就意味著你可以通過登入到電腦的憑證驗證使用者。最重要的是,根據你使用的配置和網路結構,你可以提供一個無需單獨登入步驟的“隱藏”驗證機制,瀏覽器只使用目前使用者已登入的身份。
- 為多種類型的應用程式提供一個單獨的驗證模型
- 你可以為 Web 服務、ASP.NET 程式和基於 WCF 的服務使用相同的驗證模型。Windows 驗證可使你擺脫讓身份資訊在電腦彼此之間流動的痛苦工作。
- 允許使用身份類比和 Windows 安全機制
- 例如,可以設定 Windows 的檔案存取權限控制對檔案的訪問。但是要記住非常重要的一點,這些設定不會自動起作用。因為 Web 程式預設以一個固定的賬戶身份運行(IIS 7.x 通常是 Network Service),你可以謹慎的使用 Windows 驗證 和身份類比改變這一行為。
2. 為什麼不使用 Windows 驗證?
Windows 驗證有潛在的風險,Windows 使用者帳號可能擁有對 Web 服務器或者其他網路內機器的許可權。你不會冒險給網站使用者授予這些許可權吧?
IIS 使用的一些驗證的方法需要使用者在他們的機器上有相應的軟體。這使得使用非微軟作業系統或沒有 IE 瀏覽器的使用者就無法使用它。
Windows 驗證沒有給你任何對驗證過程的控制。無法通過編程管理 Windows 賬戶資訊,也無法儲存使用者特定的資訊。
3. Windows 驗證機制
部署 Windows 驗證時,IIS 有 3 種策略對它每次收到的請求進行驗證。
- Basic 驗證:使用者名稱和密碼以純文字的格式傳遞。作為 HTML 標準的一部分,這是唯一被所有瀏覽器支援的驗證模式
- Digest 驗證:使用者名稱和密碼不傳遞,相反,一個已加密的安全地散列字串被發送
- 整合 Windows 驗證:使用者名稱和密碼不被傳遞。已登入到 Windows 系統的使用者的身份被作為一個令牌自動傳遞。
3.1 Basic 驗證
支援最廣泛的驗證協議是 Basic 驗證。用戶端驗證時,瀏覽器顯示一個登入框用來輸入使用者名稱和密碼。當使用者提供了資訊後,資訊被傳送到 Web 服務器,一旦 IIS 收到驗證資料,它會使用相應 Windows 帳號來驗證網站使用者。
Basic 驗證的關鍵限制在於它是不安全的,至少它本身是不安全的。使用者名稱和密碼以純文字格式傳輸,資料以 Base64 的形式編碼(非加密)為字串,網路竊聽者可以非常容易的讀取。
只在安全的場合下使用 Basic 驗證。比如,無需保護使用者憑證資訊的環境下,或和一個 HTTP 網路加密協議(如 SSL)捆綁時。
3.2 Digest 驗證
也需要使用者通過瀏覽器顯示的登入對話方塊提供帳號資訊。但不同的是,Digest 驗證傳遞密碼的散列串,而不是密碼本身,這樣你沒有使用 SSL 也可以防止密碼被竊取。
使用 Digest 驗證使用者的過程如下:
- 未經驗證的用戶端請求一個受限的網頁
- 伺服器返回一個 HTTP 401 響應。這個響應含有一個 nonce 值(一個隨機產生的字元序列),Web 服務器發送 nonce 前會確保它的唯一性
- 用戶端使用這個 nonce、密碼、使用者名稱和其他一些值建立一個散列。散列串與純文字的使用者名稱一起被發回伺服器
- 伺服器使用 nonce 值、為目前使用者儲存的密碼及其他一些值建立一個散列串,然後與用戶端發來的散列串匹配以確定驗證成功與否
對於每個驗證請求,nonce 值都會變化,這確保了安全機制。但 IIS Digest 驗證的一個限制是需要驗證的虛擬目錄必需在一個 Windows 活動目錄網域控制站上運行或者受其控制才能起作用。
3.3 整合 Windows 驗證
這個模式對於基於廣域網路或基於區域網路的企業內連網應用程式是最方便的驗證標準,它無需執行任何用戶端的互動即可執行驗證。當 IIS 要求用戶端驗證時,瀏覽器會發送一個代表目前使用者的 Windows 賬戶身份的標誌,但如果 Web 服務器無法使用這個資訊進行驗證,它會顯示一個登入框讓使用者輸入一個不同的使用者名稱和密碼。
用戶端和 Web 服務器必須在同一個區域網路或企業內連網上。這是因為整合 Windows 驗證實際上並不發送使用者名稱和密碼資訊。相反,它和它所屬的網域服務器或者活動目錄執行個體互相協作,以此登入並獲得將驗證資訊發送到 Web 服務器的用戶端機器上。
用來傳輸驗證資訊的協議有兩個:NTLM(NT LAN Manager,NT 區域網路管理)驗證和 Kerberos 5,根據用戶端和伺服器作業系統的版本進行選擇。如果用戶端和伺服器端作業系統的版本都在 Windows 2000或者更高,而且兩台機器都運行在一個活動目錄中,Kerberos 被用作驗證協議,否則使用 NTLM 驗證。
3.3.1 NTLM 驗證
NTLM 驗證 通過一種基於用戶端和伺服器端三向握手的 盤問/響應 機制來驗證用戶端。
- 用戶端向伺服器端發送資訊,表示想和伺服器進行通訊。
- 伺服器產生一個 64位 的隨機值 nonce(當前值)緩衝之,並向用戶端返回 nonce 以響應用戶端的請求。這個響應稱為盤問(challenge)。
- 用戶端作業系統要求使用者輸入使用者名稱和密碼,然後自動散列化之。這個散列密碼成為主要金鑰(master key),用來對 nonce 加密。隨後將加密後的 nonce 和使用者名稱作為對伺服器的響應。
- 伺服器檢驗返回的 nonce。根據使用者是本機使用者還是域使用者,檢驗會在本地發生或網域控制站上發生。使用者的主要金鑰(即密碼的散列版本)會從安全賬戶資料庫中取出,然後對伺服器上的純文字 nonce 進行加密。如果重建的 nonce 加密版本和用戶端返回的加密版本匹配,則使用者驗證成功。
- 在伺服器上為目前使用者建立一個登入工作階段。
整個過程,密碼從來都不會在網路上進行傳輸,這使得 NTLM 非常安全,但還有另一種更安全的協議。
3.3.2 Kerberos 驗證簡介
就目前來講,Kerberos 5 是最安全的協議。它是由 IETF(Internet Engineering Task Force,網際網路工程工作群組)建立的一個著名的公用標準,實現了一個基於票據的驗證協議。如果啟用了整合的 Windows 驗證,在下面的情況中會自動使用 Kerberos。
- 用戶端和伺服器端都運行在 Windows 2000 或更高版本
- 網路中存在一個首要網域控制站(扮演密鑰分發中心的角色)的活動目錄域
Kerberos 的內容能寫一本書。這裡只學習一些基本概念來協助理解必需的配置任務以及每一個功能在什麼時候會起作用。比如 NTLM 和 Kerberos 之間一個很大的區別就是 Kerberos 同時支援身份類比和委託,而 NTLM 只支援身份類比。
Kerberos 系統的核心組件是 KDC(Key Distribution Center,密鑰分發中心),負責發送票據和管理憑證。在 Windows 世界裡,活動目錄的首要網域控制站扮演著 KDC 的角色。驗證過程涉及的每一個參與者(用戶端和伺服器)必須信任 KDC。KDC 管理所有使用者和電腦的帳號,並發送驗證票據和會話票據。
Kerberos 和 NTLM 還有另外一個很大的不同:NTLM 在工作群組環境下運行,無需中央授權。Kerberos 則需要一個中央授權來發送任意類型的票據,因此,要使 Kerberos 起作用,需要串連到一個活動目錄的網域控制站。
Kerberos 驗證和票據的基本流程:
- 用戶端提交一個請求到驗證服務,驗證服務運行在 KDC(活動目錄網域控制站)上面。請求包含使用者名稱,KDC 從安全帳號資料庫中讀取使用者的主要金鑰(密碼的散列版本)。
- 它建立一個 TGT(Ticket-Granting Ticket,票據授予票據)。包含一個用於使用者會話的工作階段金鑰以及一個到期日期的時間。伺服器使用使用者的主要金鑰對 TGT 進行加密,然後發送會用戶端。
- 用戶端只有輸入正確的密碼,用戶端作業系統才能建立相同的主要金鑰(散列)來成功解密從伺服器接收到的 TGT。解密成功,驗證通過。
- 用戶端將 TGT 在本機快取。
- 當用戶端想和網路中的一台成員伺服器通訊時,首先向 KDC 請求一個會話票據。為此,它將一個在本機快取的 TGT 發送到 KDC 上的票據授予服務。這個服務檢查 TGT,如果 TGT 有效(沒有到期、沒有被篡改等),它就為這個用戶端和成員伺服器之間的通訊建立一個工作階段金鑰,然後使用用戶端的主要金鑰對這個工作階段金鑰進行加密。此外,這個工作階段金鑰被打包到 ST(Session Ticket,會話票據),ST 包含了額外的到期資訊。這個會話票據使用成員伺服器的主要金鑰進行加密。當然,伺服器和用戶端都必須被 KDC 所知,也就是之前它們二者都被添加到了域中(域中增加一個機器意味著這個機器和 KDC 之間建立一個信任關係)。因此,KDC 知道用戶端和成員伺服器的主要金鑰。
- 被加密的工作階段金鑰和會話票據都被傳送到用戶端。
- 用戶端解密工作階段金鑰,並在本機快取中儲存工作階段金鑰的副本。
- 用戶端把加密的工作階段金鑰傳送到伺服器。
- 如果伺服器可以成功解密並驗證從用戶端接收的會話票據,就會建立通訊會話。
- 用戶端和伺服器端都使用先前產生的工作階段金鑰對通訊傳輸進行加密。一旦會話票據到期,整個操作會重來一遍。
每一個票據(會話票據、票據授予票據)都有一定的功能。這些功能只是某些特性(如身份類比或委託)所需的一組定義好的屬性。比如,有了特定的屬性,它們可以在伺服器上類比用戶端使用者的身份或者將用戶端身份委託給另外一個伺服器。