2012-03-13 7 views
14

Estoy escribiendo que un servicio WCF requiere personificación y sesión.
vinculante netTCP Negociación de Seguridad de Soil Falló

Es bien cuando traté de llamarlo en mi máquina local, pero en la máquina remota que siempre ha fallado con el error de este tipo:

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.

Si he proporcionado un UPN, que arroja una identidad falló excepción .

Aquí es mi config:

de configuración del servidor (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> 

configuración del cliente:

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

Cualquier ayuda sería muy apreciada.

Respuesta

19

Los servicios de Windows se registran con un nombre de usuario principal o un nombre principal de servicio (documentation). Para citar de ese enlace: "Si el servicio se ejecuta en las cuentas LocalSystem, LocalService o NetworkService, se genera un nombre principal de servicio (SPN) de forma predeterminada en forma de host/porque esas cuentas tienen acceso a los datos SPN de la computadora Si el servicio se ejecuta con una cuenta diferente, Windows Communication Foundation (WCF) genera un UPN en forma de @. "De hecho, esta cita es bastante similar a lo que indica su mensaje de error. Así que parece que ...

a) si el servicio se está ejecutando bajo la cuenta de servicio local o una cuenta estándar similar, entonces usted necesita ajustar su cliente fichero de configuración a tener esto, donde el nombre del servidor real es " dirección" y el punto final se ejecuta en el puerto 4503:

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

b) alternativamente, si está ejecutando bajo una cuenta de servicio dedicado (vamos a llamarlo 'ServiceAccount' en el dominio 'MiDominio'), entonces usted quiere

<identity> 
    <userPrincipalName value="[email protected]" /> 
</identity> 

Tenga en cuenta que es posible que necesite utilizar el nombre de dominio completo en ambos casos, incluidos los niveles de bosque y árbol. Para un dominio simple dentro de su LAN/WAN privada, eso significará address.MyDomain.local y [email protected] Si su dominio está en un árbol llamado MyTree, será [email protected]; si eso está en un bosque llamado MyForest, será [email protected] (y similar para ServicePrincipalName). El nombre completo es necesario when you are using Kerberos para la autenticación.

+1

Esto es correcto. También agregaré que, al consumir servicios web alojados en IIS, la identidad debe coincidir con la identidad del grupo de aplicaciones en el que vive el servicio. ¿Esto fue cambiado en alguna versión de IIS (quizás 7?) De NetworkService (donde utilizaría un principio de usuario de 'NetworkService @ MACHINE-NAME') para AppPoolIdentity (donde usaría un principio de servicio de' host/MACHINE-NAME') – qJake

6

También hay un truco sucio, tal como fue anunciado here, here y here, y analizado here.

Puede suministrar un nombre principal de servicio ficticio (SPN). En ese caso, WCF no fallará, pero recurrirá a NTLM para autenticación que no verifica el principal.

Así, configuración:

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

y programáticamente

EndpointIdentity identity = EndpointIdentity.CreateSpnIdentity("dummy"); 

usando ChannelFactory:

Uri uri = new Uri("net.tcp://<myServer>:<myPort>/myServiceAddress"); 
    ChannelFactory channelFactory = new ChannelFactory<IMyContract>(new NetTcpBinding()); 
    channelFactory.CreateChannel(new EndpointAddress(uri, identity) 

también funcionará.

Cuestiones relacionadas