Asp.net

401 客戶端“協商”,伺服器“協商,NTLM”在呼叫 WCF 伺服器到伺服器時

  • December 7, 2020

好的,我已經閱讀了我可以找到的每個執行緒和問題,但令人驚訝的是還沒有找到解決方案。我試圖在我的 IIS 託管 WCF 服務 (.NET 4.0) 上要求 Windows 身份驗證,到目前為止,該服務一直是可選的。我在伺服器上有一個啟用 Windows 身份驗證的端點已經有一段時間了,有幾個遠端應用程序成功使用了它。我現在正嘗試將我們的 Web 應用程序和其他使用 WCF 服務的伺服器應用程序切換到此安全端點,方法是為它們提供與工作遠端客戶端完全相同的客戶端配置,但伺服器應用程序正在接收帶有消息的 401:

The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'.]

我為 WCF 託管站點啟用了匿名和 Windows 身份驗證。我開始使用的 Web 應用程序託管在與 WCF 服務不同的伺服器上,並且在 ASP.NET 2.0 和 Windows Server 2008 R2 Enterprise 上執行。我已經使用 allowNtlm 創建了一個客戶端行為,並將 NetworkSecurity: LAN Manager 身份驗證級別設置為 Send LM & NTLM… 在客戶端。在託管端,它設置為僅發送 NTLMv2 響應…我不知道這是否會影響伺服器/服務處理身份驗證的方式。我還嘗試在客戶端上將 allowedImpersonationLevel 設置為 Impersonation ,謝天謝地,這不起作用(因為不需要模擬)。對於在與 Web 應用程序相同的伺服器上執行的 Windows 服務和控制台應用程序,我們似乎得到了相同的結果。

這是我的伺服器配置:

<binding name="WindowsSecuredBinding">
   <security mode="Transport">
       <transport clientCredentialType="Windows" />
   </security>
</binding>
...
<service behaviorConfiguration="OMWebServices.QueueServiceBehavior"
   name="OMWebServices.QueueService">
   <endpoint address="" binding="basicHttpBinding" name="QueueEndpoint"
     bindingName="" contract="OMWebServices.IQueueService" />
   <endpoint binding="basicHttpBinding" bindingConfiguration="WindowsSecuredBinding"
     name="QueueSecuredEndpoint" contract="OMWebServices.IQueueService" />
   <endpoint address="mex" binding="mexHttpBinding" name="QueueMetadataEndpoint"
     contract="IMetadataExchange" />
 </service>
...
<behavior name="OMWebServices.QueueServiceBehavior">
   <serviceMetadata httpGetEnabled="true" />
   <serviceDebug includeExceptionDetailInFaults="true" />
</behavior>

這是客戶端配置:

<endpoint address="https://.../QueueService.svc" binding="basicHttpBinding" bindingConfiguration="QueueSecuredEndpoint" behaviorConfiguration="OMServiceBehavior" contract="OMQueueService.IQueueService" name="QueueSecuredEndpoint" />

<binding name="QueueSecuredEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
 <security mode="Transport">
   <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
   <message clientCredentialType="UserName" algorithmSuite="Default" />
 </security>
</binding>
....
<!-- The behavior I tried that didn't make a difference -->
<behavior name="OMServiceBehavior">
 <clientCredentials>
   <windows allowedImpersonationLevel="Impersonation" allowNtlm="True"/>
 </clientCredentials>
</behavior>

我的第一個問題是,這條錯誤消息真正告訴我的是什麼?它說客戶端方案是協商,伺服器響應協商,NTLM。如果伺服器提供 Negotiate 並且客戶端正在使用 Negotiate,那麼問題是什麼?

第二個問題是,顯然,出了什麼問題,我該如何讓它發揮作用?

編輯

好吧,這很愚蠢。問題似乎是沒有傳遞憑據。早在網站開發時,我就開始編寫程式碼以在程式碼中顯式設置憑據,但在此過程中,發現它已經在沒有顯式設置的情況下工作。所以該程式碼仍然被註釋掉。這是在 IIS 6 上執行的。現在在 IIS 7 上執行,它似乎只有在我在程式碼中明確設置憑據時才有效。我可以使用 w3wp 程序的帳戶自動獲取它嗎?

為了回答第一個問題,錯誤消息告訴我它到底在說什麼;我沒有被授權。告訴我客戶端身份驗證方案和伺服器標頭的行只是額外的資訊,而不是衝突的指示。它實際上是確認配置是正確的。

在暫存環境中,問題被掩蓋了,因為 WCF 服務和 Web 應用程序託管在同一台伺服器上。問題是 Web 應用程序的站點預設配置為對匿名使用者使用本地帳戶 IUSR(或 IUSR_Server)。這是正在傳遞的使用者(我相信它等於 CredentialCache.DefaultNetworkCredentials)。當它們在不同的伺服器上時,伺服器 2 上的 WCF 顯然無法對伺服器 1 使用者進行身份驗證。解決方案在 IIS 中,右鍵點擊匿名身份驗證 > 編輯…> 檢查應用程序池標識(在我的情況下是域帳戶)或輸入特定使用者的域帳戶。

引用自:https://stackoverflow.com/questions/22460150