数日前、クライアントとwcf Webサービスの間でWindows認証を使用するときに、認証の問題でかなりの頭痛の種がありました。「HTTPリクエストはクライアント認証スキーム「ネゴシエート」で許可されていません。サーバーから受信した認証ヘッダーは「NTLM」でした。スタック上のソリューションのほとんどは古いメソッドに関連しているため、機能しませんでした。
6 に答える
回答:問題は、そのような問題のすべての投稿が、プロキシクレデンシャルまたはAllowNTLMプロパティが役立つ古いKerberosおよびIISの問題に関連していたことでした。私の場合は違いました。何時間にもわたってワームを地面から拾い上げた後に私が発見したのは、IISのインストールにIISWindows認証プロバイダーリストのネゴシエートプロバイダーが含まれていないことでした。だから私はそれを追加して上に移動しなければなりませんでした。WCFサービスが期待どおりに認証を開始しました。これは、匿名認証をオフにしてWindows認証を使用している場合のスクリーンショットです。
Windows認証を右クリックして、プロバイダーメニュー項目を選択する必要があります。
これが時間を節約するのに役立つことを願っています。
以前のバージョンのWCFを以下の変更を加えてWCF4にアップグレードしました。同様の変更を加えられることを願っています。
1. Web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Demo_BasicHttp">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="InheritedFromHost"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="DemoServices.CalculatorService.ServiceImplementation.CalculatorService" behaviorConfiguration="Demo_ServiceBehavior">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="Demo_BasicHttp" contract="DemoServices.CalculatorService.ServiceContracts.ICalculatorServiceContract">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Demo_ServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="Demo_BasicHttp"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
2. App.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ICalculatorServiceContract" maxBufferSize="2147483647" maxBufferPoolSize="33554432" maxReceivedMessageSize="2147483647" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<readerQuotas maxArrayLength="2147483647" maxBytesPerRead="4096" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:24357/CalculatorService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICalculatorServiceContract" contract="ICalculatorServiceContract" name="Demo_BasicHttp" />
</client>
</system.serviceModel>
私にとっての解決策は、クレデンシャルタイプとして「Ntlm」を使用する以外にありました。
XxxSoapClient xxxClient = new XxxSoapClient();
ApplyCredentials(userName, password, xxxClient.ClientCredentials);
private static void ApplyCredentials(string userName, string password, ClientCredentials clientCredentials)
{
clientCredentials.UserName.UserName = userName;
clientCredentials.UserName.Password = password;
clientCredentials.Windows.ClientCredential.UserName = userName;
clientCredentials.Windows.ClientCredential.Password = password;
clientCredentials.Windows.AllowNtlm = true;
clientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
}
この正確な問題ではありませんが、これはほぼ同じエラーをグーグルで検索した場合の最高の結果です。
同じマシンでホストされているWCFサービスの呼び出しでこの問題が発生した場合は、BackConnectionHostNames
レジストリキーを入力する必要があります。
- regeditで、次のレジストリサブキーを見つけてクリックします。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
- 右クリックし、[
MSV1_0
新規]をポイントして、[]をクリックしますMulti-String Value
。 - [名前]列にと入力
BackConnectionHostNames
し、Enterキーを押します。 - を右クリック
BackConnectionHostNames
し、[変更]をクリックします。[値のデータ]ボックスに、コンピューターのローカル共有に使用されているCNAMEまたはDNSエイリアスを入力し、[OK]をクリックします。- 各ホスト名を別々の行に入力します。
詳細については、クライアントが認証エラーをスローするのと同じマシンでIISでホストされているWCFサービスを呼び出すを参照してください。
私にとっての解決策は、AppPoolがAppPoolIdentityを使用することからNetworkServiceIDに設定することでした。