共用方式為


整合式 Windows 驗證與擴充保護

增強功能改進了在HttpWebRequest和相關命名空間中的HttpListenerSmtpClientSslStreamNegotiateStreamSystem.Net及相關類別如何處理整合式 Windows 驗證。 已新增擴充保護的支援,以增強安全性。

這些變更可能會影響使用這些類別來提出 Web 要求,並在使用整合式 Windows 驗證時接收回應的應用程式。 這項變更也會影響設定為使用整合式 Windows 驗證的 Web 伺服器和用戶端應用程式。

這些變更也會影響使用這些類別的應用程式,以提出其他類型的要求,並接收使用整合式 Windows 驗證的回應。

支援擴充保護的變更僅適用於 Windows 7 和 Windows Server 2008 R2 上的應用程式。 舊版 Windows 不提供擴充保護功能。

概觀

整合式 Windows 驗證的設計可讓某些認證挑戰回應成為通用,這表示可以重複使用或轉送它們。 挑戰回應至少應包含目標特定資訊,最好還包含一些渠道特定資訊。 接著,服務可以提供擴充保護,以確保認證挑戰回應包含服務特定資訊,例如服務主體名稱(SPN)。 有了認證交換中這項資訊,服務就能夠更妥善地防範可能未正確使用認證挑戰回應的惡意使用。

延伸保護設計是驗證通訊協議的增強功能,旨在減輕驗證轉送攻擊。 它圍繞著通道和服務綁定資訊的概念。

整體目標如下:

  1. 如果用戶端更新為支援擴充保護,應用程式應該提供通道系結和服務系結資訊給所有支援的驗證通訊協定。 通道系結資訊只能在有要系結的通道 (TLS) 時提供。 應該一律提供服務系結資訊。

  2. 已更新的伺服器在客戶端驗證令牌中出現通道和服務系結資訊時,可能會檢查這些系結資訊是否符合;如果通道系結不符,將拒絕驗證嘗試。 根據部署案例,伺服器可能會驗證通道系結、服務系結或兩者。

  3. 更新的伺服器能夠接受或拒絕未根據原則包含通道系結資訊的下層用戶端要求。

擴充保護所使用的資訊包含下列兩個部分之一或兩個部分:

  1. 通道綁定令牌或簡稱為 CBT。

  2. 服務系結資訊,格式為服務主體名稱或SPN。

服務系結資訊表示用戶端意圖向特定服務端點進行驗證。 它會使用下列屬性從客戶端到伺服器進行通訊:

  • SPN 值必須可供以純文字格式執行客戶端驗證的伺服器使用。

  • SPN 的值是公用的。

  • SPN 必須在傳輸時受到密碼編譯保護,如此一來,中間人攻擊就無法插入、移除或修改其值。

CBT 是一種外部安全通道(例如 TLS)的屬性,用來將其與內部、經客戶端驗證的通道結合,以支援交談。 CBT 必須具有下列屬性(亦由 IETF RFC 5056 定義):

  • 當外部通道存在時,CBT 的值必須是由交談中的用戶端和伺服器端各自獨立確定的屬性,以識別外部通道或伺服器端點。

  • 用戶端傳送的 CBT 值絕不能是攻擊者可能會影響的值。

  • 不保證 CBT 值的保密性。 然而,這並不表示服務系結和通道系結資訊的值一律可被伺服器以外的其他任何系統檢查,因為攜帶 CBT 的通訊協定可能會加密此資訊。

  • CBT 必須在傳輸中受到密碼編譯完整性保護,攻擊者無法插入、移除或修改其值。

通道系結是由用戶端以防竄改方式將SPN和 CBT 傳輸至伺服器來完成。 伺服器會根據其原則驗證通道繫結資訊,並拒絕那些伺服器認為自己不是預定目標的驗證嘗試。 如此一來,這兩個通道會以密碼編譯方式系結在一起。

為了保留與現有用戶端和應用程式的相容性,伺服器可能會設定為允許尚未支援擴充保護的用戶端進行驗證嘗試。 這稱為「部分強化」組態,與「完全強化」組態相反。

System.Net 命名空間中的System.Net.Security多個元件代表呼叫應用程式執行整合式 Windows 驗證。 本節說明 System.Net 元件的變更,以在其使用整合式 Windows 驗證時新增擴充保護。

Windows 7 目前支援擴充保護。 提供機制,讓應用程式可以判斷作系統是否支援擴充保護。

支援擴充保護的變更

與整合式 Windows 驗證搭配使用的驗證過程,依據所使用的驗證通訊協定,通常包含由目的電腦發出的挑戰,並傳回至客戶端電腦。 擴充保護會將新功能新增至此驗證程式

命名空間 System.Security.Authentication.ExtendedProtection 提供對應用程式使用擴充保護進行驗證的支援。 ChannelBinding這個命名空間中的 類別代表通道系結。 ExtendedProtectionPolicy此命名空間中的 類別代表伺服器用來驗證連入用戶端連線的擴充保護原則。 其他類別成員會與擴充保護搭配使用。

針對伺服器應用程式,這些類別包含下列專案:

具有下列元素的ExtendedProtectionPolicy

  • OSSupportsExtendedProtection屬性,指出作系統是否支援具有擴充保護的整合式 Windows 驗證。

  • PolicyEnforcement值,指出何時應強制執行擴充保護原則。

  • ProtectionScenario值,表示部署案例。 這會影響檢查擴充保護的方式。

  • 選擇性 ServiceNameCollection ,其中包含自定義SPN清單,用來比對用戶端提供的SPN做為驗證的預期目標。

  • 選擇性 ChannelBinding ,其中包含要用於驗證的自定義通道系結。 此案例並非常見案例

命名空間 System.Security.Authentication.ExtendedProtection.Configuration 支援使用應用程式的擴充保護來設定驗證。

已進行多項功能變更,以支援現有 System.Net 命名空間中的擴充保護。 這些變更包括下列各項:

已進行功能變更,以支援現有 System.Net.Mail 命名空間中 SMTP 用戶端應用程式的擴充保護:

  • TargetName類別SmtpClient中的 屬性,表示在 SMTP 用戶端應用程式使用擴充保護時,要用於驗證的 SPN。

已進行多項功能變更,以支援現有 System.Net.Security 命名空間中的擴充保護。 這些變更包括下列各項:

SmtpNetworkElement已新增 屬性,以支援命名空間中 SMTP 用戶端的擴充保護設定System.Net.Security

用戶端應用程式的擴充保護

大部分用戶端應用程式的擴充保護支援會自動進行。 每當 Windows 的基礎版本支援擴充保護時,HttpWebRequest 類別和 SmtpClient 類別都支援此擴充保護。 HttpWebRequest實例會傳送一個由Uri建構的SPN。 根據預設, SmtpClient 實例會從 SMTP 郵件伺服器的主機名傳送 SPN。

針對自定義驗證,用戶端應用程式可以使用 HttpWebRequest.EndGetRequestStream(IAsyncResult, TransportContext) 類別中的 HttpWebRequest.GetRequestStream(TransportContext)HttpWebRequest 方法,允許使用 TransportContext 方法擷取 GetChannelBinding 和 CBT。

透過設定HttpWebRequest屬性,您可以覆寫CustomTargetNameDictionary實例傳送至指定服務時使用的整合式 Windows 驗證的 SPN。

TargetName屬性可用來設定自定義 SPN,以用於 SMTP 連線的整合式 Windows 驗證。

伺服器應用程式的擴充保護

HttpListener 會自動提供在執行 HTTP 驗證時驗證服務系結的機制。

最安全的情境是為 HTTPS:// 前綴啟用擴充保護。 在這種情況下,將 HttpListener.ExtendedProtectionPolicy 設定為 ExtendedProtectionPolicy,並將 PolicyEnforcement 設定為 WhenSupportedAlways,同時將 ProtectionScenario 設定為 TransportSelectedWhenSupported 的值會將 HttpListener 置於部分強化模式,而 Always 則對應至完全強化模式。

在這種配置中,透過外部安全通道向伺服器提出要求時,外部通道會被查詢以獲取通道繫結。 此通道系結會傳遞至驗證 SSPI 呼叫,以驗證驗證 Blob 中的通道系結是否相符。 有三個可能的結果:

  1. 伺服器的基礎作系統不支援延伸保護。 要求不會公開給應用程式,且未經授權的 (401) 回應會傳回給用戶端。 系統會將訊息記錄到追蹤來源, HttpListener 以指定失敗的原因。

  2. SSPI 呼叫失敗,指出用戶端指定的通道系結不符合從外部通道擷取的預期值,或者當伺服器上 Always設定擴充保護原則時,客戶端無法提供通道系結。 在這兩種情況下,要求都不會公開給應用程式,且未經授權的 (401) 回應會傳回給用戶端。 系統會將訊息記錄到追蹤來源, HttpListener 以指定失敗的原因。

  3. 用戶端可以指定正確的通道系結,或者在沒有指定通道系結的情況下被允許連線,因為伺服器上的擴充保護原則設定為 WhenSupported。然後,請求將被傳回給應用程式進行處理。 系統不會自動執行服務名稱檢查。 應用程式可以選擇使用 ServiceName 屬性執行自己的服務名稱驗證,但在這種情況下,這是多餘的。

如果應用程式發出自己的 SSPI 呼叫,以根據 HTTP 要求主體內傳來回的 Blob 來執行驗證,而且想要支援通道系結,它就必須使用 HttpListener 從外部安全通道擷取預期的通道系結,才能將它傳遞至原生 Win32 AcceptSecurityContext 函式。 若要這樣做,請使用 TransportContext 屬性和呼叫 GetChannelBinding 方法來擷取 CBT。 僅支援端點系結。 如果指定任何其他 Endpoint,將擲回 NotSupportedException。 如果基礎作系統支援通道系結,此方法 GetChannelBinding 會傳回 ChannelBindingSafeHandle 包裝通道系結的指標,該系結適合傳遞至 AcceptSecurityContext 函式,做為傳入 pInput 參數之 SecBuffer 結構的 pvBuffer 成員。 屬性 Size 包含通道系結的長度,以位元組為單位。 如果基礎作系統不支援通道系結,函式會傳回 null

另一個可能的情境是在不使用代理伺服器時,為前綴啟用擴充保護。 在這種情況下,將 HttpListener.ExtendedProtectionPolicy 設定為 ExtendedProtectionPolicy,並將 PolicyEnforcement 設定為 WhenSupportedAlways,同時將 ProtectionScenario 設定為 TransportSelectedWhenSupported 的值會將 HttpListener 置於部分強化模式,而 Always 則對應至完全強化模式。

預設允許的服務名稱清單是根據已註冊的HttpListener前置詞來建立的。 您可以透過 DefaultServiceNames 屬性檢查此預設清單。 如果這份清單不完整,應用程式可以在 ExtendedProtectionPolicy 類別的建構函式中指定自定義的服務名稱集合,這將取代預設的服務名稱清單來使用。

當針對伺服器的請求未使用外部安全通道驗證時,認證將正常進行,無需進行通道系結檢查。 如果驗證成功,則會針對用戶端所提供的服務名稱查詢內容,並針對可接受的服務名稱清單進行驗證。 有四個可能的結果:

  1. 伺服器的基礎作系統不支援延伸保護。 要求不會公開給應用程式,且未經授權的 (401) 回應會傳回給用戶端。 系統會將訊息記錄到追蹤來源, HttpListener 以指定失敗的原因。

  2. 用戶端的基礎作系統不支援延伸保護。 在組態中 WhenSupported ,驗證嘗試將會成功,並將要求傳回至應用程式。 在設定中 Always ,驗證嘗試將會失敗。 要求不會公開給應用程式,且未經授權的 (401) 回應會傳回給用戶端。 系統會將訊息記錄到追蹤來源, HttpListener 以指定失敗的原因。

  3. 用戶端的基礎作系統支援擴充保護,但應用程式未指定服務系結。 要求不會公開給應用程式,且未經授權的 (401) 回應會傳回給用戶端。 系統會將訊息記錄到追蹤來源, HttpListener 以指定失敗的原因。

  4. 用戶端指定服務系結。 服務系結會與允許的服務系結清單進行比較。 如果符合,則會將要求傳回至應用程式。 否則,不會向應用程式公開要求,且未經授權的 (401) 回應會自動傳回給用戶端。 系統會將訊息記錄到追蹤來源, HttpListener 以指定失敗的原因。

如果使用允許的服務名稱清單的這個簡單方法不足,應用程式可能會藉由查詢 ServiceName 屬性來提供自己的服務名稱驗證。 在上述 1 和 2 的情況下,屬性會傳回 null。 如果為 3,則會傳回空字串。 如果為 4,則會傳回用戶端所指定的服務名稱。

伺服器應用程式也可以使用這些擴充的保護功能,來對其他類型的請求進行驗證,並在使用信任的代理伺服器時使用。

另請參閱