NetTCPバインディングSOAPセキュリティネゴシエーションに失敗しました
-
13-12-2019 - |
質問
私はWCFサービスを書いています。
ローカルマシンでそれを呼び出しようとしましたが、リモートマシンでは常にそのようなエラーで失敗しました:
セキュリティサポートプロバイダインタフェース(SSPI)認証に失敗しました。サーバーは、ID 'HOST / HOSTNAME'を持つアカウントで実行されていない可能性があります。サーバーがサービスアカウント(たとえばネットワークサービス)で実行されている場合は、サーバーのEndPointAddressのIDとしてアカウントのServicePrincipalNameを指定してください。サーバーがユーザーアカウントで実行されている場合は、サーバーのEndPointAddressのIDとしてアカウントのUserPrincipalNameを指定します。
UPnを提供した場合は、IDに失敗した例外をスローします。
これは私の設定です:
サーバ設定(アプリ):
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="default">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="DataService.netTcpBinding">
<readerQuotas maxArrayLength="65535" maxBytesPerRead="2147483647" maxStringContentLength="2147483647"/>
<reliableSession enabled="true" inactivityTimeout="24:00:00" ordered="true"/>
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Windows" />
<transport clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<services>
<service behaviorConfiguration="default" name="DataService.DataService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="DataService.netTcpBinding"
name="DataService.DataService" contract="DataService.IDataService"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://address:4504/"/>
<add baseAddress="net.tcp://address:4503/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
.
クライアント設定:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="DataService.DataService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="24.00:00:00"
enabled="true" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" algorithmSuite="Default" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://address:4503/" binding="netTcpBinding"
bindingConfiguration="DataService.DataService"
contract="ataService.IDataService" name="DataService.DataService">
<identity>
<dns value="DOMAIN"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
.
あらゆる助けが大いに感謝されるでしょう。
解決
Windowsサービスは、ユーザープリンシパル名またはサービスプリンシパル名(ドキュメンテーション)そのリンクから引用するには: "サービスがLocalSystem、LocalService、またはNetworkServiceアカウントで実行されている場合、サービスプリンシパル名(SPN)はデフォルトでホストの形式で生成されます。 SPNデータサービスが異なるアカウントで実行されている場合、Windows Communication Foundation(WCF)は@。の形式でUPNを生成します。実際、この引用はあなたのエラーメッセージが述べているものとはかなり似ています。だからそれは...それは...
のようですa)サービスがローカルサービスアカウントまたは類似の標準アカウントで実行されている場合は、実際のサーバーの名前が「アドレス」であるようにクライアント設定ファイルを調整する必要があります。エンドポイントはポート4503で実行されています。
<identity>
<servicePrincipalName value="host/address:4503" />
</identity>
.
b)あるいは、専用のサービスアカウントで実行している場合(ドメイン "MyDomain"で "Serviceaccount"を呼び出しましょう)、
が欲しいです。<identity>
<userPrincipalName value="ServiceAccount@MyDomain" />
</identity>
.
フォレストやツリーのレベルを含めて、両方の場合で完全修飾ドメイン名を使用する必要がある可能性があります。プライベートLAN / WAN内の単純なドメインの場合、それはaddress.mydomain.localとserviceaccount@mydomain.localを意味します。あなたのドメインがMyTreeというツリーにある場合は、serviceaccount@mydomain.mytree.localになります。それがMyForestと呼ばれるフォレストに入っている場合、それはserviceaccount@mydomain.mytree.myforest.local(そしてServicePrincipalNameの場合も同様)になります。完全修飾名は必要です。認証にKerberos を使用しています。
他のヒント
投稿された
ダミーサービスプリンシパル名(SPN)を供給することができます。その場合、WCFは失敗しません。 しかし、プリンシパルを検証しない認証のためにNTLMに戻る。
<identity>
<servicePrincipalName value="dummy" >
</identity>
.
EndpointIdentity identity = EndpointIdentity.CreateSpnIdentity("dummy");
.
Uri uri = new Uri("net.tcp://<myServer>:<myPort>/myServiceAddress");
ChannelFactory channelFactory = new ChannelFactory<IMyContract>(new NetTcpBinding());
channelFactory.CreateChannel(new EndpointAddress(uri, identity)
.