我們正在開發許多託管在IIS中的WCF服務。 (在Windows Server 2003 SP2上運行的IIS 6.0)。這些服務是爲REST設置的。對於一個環境(DEV,CERT,PROD),我們通常每個IIS服務器都有很多服務。每項服務都有自己的登錄帳戶,通過應用程序池進行分配。如何在Windows身份驗證中使用帶REST的WCF服務中的計算機名稱
這工作得很好,但是如果我們在虛擬目錄上啓用Windows身份驗證(允許用戶上下文傳遞,而不是假冒或委託),我們得到了在特定情況下的安全性的錯誤。如果我們使用ServiceEndpoint連接到C#代碼中的服務,它可以工作,但是當我們通過瀏覽器或非Wcf代碼(例如HttpWebRequest,java等)連接到服務時,我們會遇到安全錯誤。
如果我改變從協商在IIS中的身份驗證,NTLM只是NTLM,那麼它的工作原理。 真的發生了什麼是我們正在禁用Kerberos,並且由於這些服務與網絡中的其他服務器交談,我們開始發現服務無法連接到遠程服務器(通常是SQL Server)的其他問題。
現在,這裏的怪異的一部分,如果我們把這臺機器一個DNS別名(CNAME記錄),並使用URL與它的工作原理的別名。 例如
http://dnsalias/service/myservice.svc/foo WORKS!
but
http://machinename/service/myservice.svc/foo FAILS :(
我們不能讓所有這些機器的DNS別名(這一直是我們解決了這一點),因爲我們已經開始廣泛使用的虛擬機和旋轉,並上下。所以我們只有機器名稱,我們不想在機器上啓動腳本編寫DNS別名。
現在我知道了SPN的問題,但是,因爲我們託管在同一網站(默認網站一般)上的多個服務,我們只能創建每個服務器/客戶1個服務主體名稱。由於我們每個服務器託管多個服務,每個服務器都映射到自己的帳戶,所以這不是解決方案
setspn -a HTTP//WCFServer.domain.com customDomainAccount
另一個問題是,我們沒有在配置文件中定義端點,只在代碼中,這裏是獲取REST綁定的代碼。
protected internal static Binding GetWebHttpBinding()
{
// Create a new binding with Authentication enabled
var binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);
// Set defaults
SetTimeouts(binding);
SetReaderQuotas(binding.ReaderQuotas);
binding.MaxReceivedMessageSize = MaxReceivedMessageSize;
binding.MaxBufferSize = 65536;
// Set the Credential type to Windows to allow single sign-on
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
// Need Streamed Response since Transport security does not allow streamed requests
binding.TransferMode = TransferMode.StreamedResponse;
return binding;
}