2012-03-13 7 views
14

私はWCFサービスを作成していますが、偽装とセッションが必要です。
netTCPバインドソープセキュリティのネゴシエーションに失敗しました

私は私のローカルマシン上でそれを呼び出すようにしようとしたとき、それはOKですが、リモートマシン上で、それは常に、このようなエラーで失敗しました:

Security Support Provider Interface (SSPI) authentication failed. The server may not be running in an account with identity 'host/hostname'. If the server is running in a service account (Network Service for example), specify the account's ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account's UserPrincipalName as the identity in the EndpointAddress for the server.

私がUPNを提供している場合、それはアイデンティティが例外を失敗したスロー。ここで

私の設定です:

Serverのコンフィグレーション(APP):

<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> 

任意の助けいただければ幸いです。

答えて

19

Windowsサービスは、自分自身をユーザープリンシパル名またはサービスプリンシパル名(documentation)で登録します。 "サービスがLocalSystem、LocalService、またはNetworkServiceのいずれかのアカウントで実行されている場合、サービスプリンシパル名(SPN)は、コンピュータのSPNデータにアクセスできるため、デフォルトではhost /という形式で生成されますサービスが別のアカウントで実行されている場合、Windows Communication Foundation(WCF)は@。の形式でUPNを生成します。 "実際、この見積もりは、エラーメッセージの記述と似ています。だから、どこ実際のサーバーの名前が "ある、サービスはローカルサービスアカウントまたは同様の標準的なアカウントで実行されている場合

a)は、その後、あなたがこれを持っているあなたのクライアント設定ファイルを調整する必要がある...ということらしいです住所:MyDomainの 『『ドメイン上の』ServiceAccount)」およびエンドポイントがポート4503で実行されている専用のサービスアカウントで実行されている場合は、交互に

<identity> 
    <servicePrincipalName value="host/address:4503" /> 
</identity> 

B)(さんがそれを呼びましょう』、あなたは

をしたいです
<identity> 
    <userPrincipalName value="[email protected]" /> 
</identity> 

フォレストとツリーのレベルを含め、両方の場合に完全修飾ドメイン名を使用する必要があることに注意してください。プライベートLAN/WAN内のシンプルなドメインの場合は、address.MyDomain.localと[email protected]を意味します。あなたのドメインがMyTreeというツリーにある場合、それは[email protected]になります。それがMyForestという名前のフォレストにある場合、Serviceaccount @ MyDomain.MyTree.MyForest.local(およびServicePrincipalNameに似ています)になります。完全修飾名は、認証のためにwhen you are using Kerberosが必要です。

+1

これは正しいです。また、IISによってホストされるWebサービスを消費する場合、IDはサービスが存在するアプリケーションプールIDと一致する必要があります。これは、あるバージョンのIIS(おそらく7?)からNetworkService(ここでは 'NetworkService @ MACHINE-NAME'のユーザー原則を使用する)からAppPoolIdentity(' host/MACHINE-NAME'のサービス原則を使用する) )。 – qJake

6

herehere、およびhere、 を掲載してhereを分析した汚いハックもあります。

ダミーのサービスプリンシパル名(SPN)を指定できます。その場合、WCFは失敗しません。 しかし、プリンシパルを確認しない認証のためにNTLMにフォールバックします。

ので、コンフィギュレーション:

<identity> 
     <servicePrincipalName value="dummy" > 
    </identity> 

と、プログラム

のChannelFactoryを使用して
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) 

も動作します。

関連する問題