わかりました。このエラーで見つけたすべてのスレッドと質問を読みましたが、驚くべきことに解決策が見つかりませんでした。 IISホストされたWCFサービス(.NET 4.0)でWindows認証を要求しようとしていますが、これはこれまでオプションでした。サーバーでWindows認証対応のエンドポイントを使用できます。しばらくの間、いくつかのリモートアプリケーションが正常に使用されています。現在、WCFサービスを使用するWebアプリケーションやその他のサーバーアプリを、動作中のリモートクライアントとまったく同じクライアント構成を提供することで、このセキュリティで保護されたエンドポイントに切り替えようとしています。サーバーアプリは、次のメッセージとともに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.NET2.0およびWindowsServer 2008 R2Enterpriseで実行されています。 allowNtlmを使用してクライアント動作を作成し、クライアント側でNetworkSecurity:LANManager認証レベルをSendLM&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で応答していると表示されます。サーバーがネゴシエートを提供し、クライアントがネゴシエートを使用している場合、問題は何ですか?
2番目の質問は、明らかに、何が問題であり、どうすればそれを機能させることができるかということです。
[〜#〜]編集[〜#〜]
まあ、これはばかです。問題は、渡された資格情報がないことのようです。 Webサイトが開発されていた頃、コードに資格情報を明示的に設定するコードを書き始めましたが、その過程で 明示的に設定せずにすでに機能していることがわかりました 。そのため、そのコードはコメントアウトされたままです。これはIIS 6で実行されていました。現在IIS 7で実行されています。コードで資格情報を明示的に設定した場合にのみ、機能するようです。取得できますか? w3wpプロセスのアカウントを自動的に使用しますか?
最初の質問に答えるために、エラーメッセージはそれが何を言っているかを正確に教えてくれます。私は許可されていません。クライアント認証スキームとサーバーヘッダーを示す行は単なる追加情報であり、競合を示すものではありません。実際には、構成が正しいことを確認しています。
ステージング環境では、WCFサービスとWebアプリケーションが同じサーバーでホストされているため、問題がマスクされています。問題は、Webアプリのサイトが、デフォルトで匿名ユーザーに対してローカルアカウントであるIUSR(またはIUSR_Server)を使用するように構成されていることです。これは渡されるユーザーです(これはCredentialCache.DefaultNetworkCredentialsと等しいと私は信じています)。それらが異なるサーバー上にある場合、サーバー2のWCFは明らかにサーバー1ユーザーを認証できません。解決策はIISにあり、[匿名認証]> [編集...]を右クリック> [アプリケーションプールID](私の場合はドメインアカウント)を確認するか、特定のユーザーのドメインアカウントを入力します。
これは、クライアントとサーバーが異なる認証スキームを使用していることを意味します。
クライアント構成で、
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
とメッセージセキュリティ
<message clientCredentialType="UserName" algorithmSuite="Default" />
そのため、このためにエラーが発生する可能性があります。これらのリンクはあなたを助けるかもしれません。
また、クライアント構成で
<endpoint address="https://.../QueueService.svc" binding="basicHttpBinding" bindingConfiguration="QueueSecuredEndpoint" behaviorConfiguration="OMSServiceBehavior" contract="OMQueueService.IQueueService" name="QueueSecuredEndpoint" />
BehaviorConfigurationをbehaviorConfiguration="OMSServiceBehavior"
からbehaviorConfiguration="OMWebServices.QueueServiceBehavior"
に変更します
また、TransportCredentialOnly
を使おうとしましたか?そうでない場合は、これを試してみるとよいでしょう http://msdn.Microsoft.com/en-us/library/ff648505.aspx
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
このエラーに関する私の問題は、構成に関連するものではなく、 同じマシン上の別のサービスを呼び出すWCFサービス に固有のものでした。
これは、C#コンソールアプリを介して部分的にプロビジョニングされた新しいサーバーのフリートに影響を与えたため、影響を受けたサーバーを介して次のようなコードを実行することで解決しました。
const string userRoot = "HKEY_LOCAL_MACHINE";
const string subkey = @"SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0";
const string keyName = userRoot + @"\" + subkey;
Registry.SetValue(keyName, "BackConnectionHostNames", hostnamesOnServer.ToArray(), RegistryValueKind.MultiString);
Windows Server2012では再起動は必要ありませんでした。