сбой согласования безопасности привязки Soap netTCP

Я пишу службу WCF, которая требует олицетворения и сеанса.

это нормально, когда я пытался вызвать его на своей локальной машине, но на удаленной машине он всегда терпел неудачу с такой ошибкой:

ошибка проверки подлинности интерфейса поставщика поддержки безопасности (SSPI). Возможно, сервер не работает в учетной записи с идентификатором "host / hostname". Если сервер работает в учетной записи службы (например, сетевой службы), укажите учетную запись ServicePrincipalName как идентификатор в EndpointAddress для сервера. Если сервер работает в учетной записи пользователя, укажите имя пользователя UserPrincipalName в качестве идентификатора в EndpointAddress для сервера.

Если я предоставил upn,он выдает исключение Identity failed.

вот мой конфиг:

конфигурация сервера (приложение):

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

любая помощь была бы весьма признательна.

2 ответов


службы Windows регистрируются либо с именем участника-пользователя, либо с именем участника-службы (документация). Цитата из этой ссылки: "если служба выполняется под учетной записью LocalSystem, LocalService или NetworkService, имя участника-службы (SPN) создается по умолчанию в виде host/, поскольку эти учетные записи имеют доступ к данным SPN компьютера. Если служба работает под другой учетной записью, Windows Communication Foundation (WCF) генерирует UPN в виде @. " на самом деле, эта цитата довольно похожа на то, что говорится в вашем сообщении об ошибке. Похоже на то...

a) если служба работает под учетной записью локальной службы или аналогичной Стандартной учетной записью, вам необходимо настроить свой клиент файл конфигурации для этого, где фактическое имя сервера - "адрес", а конечная точка работает на порту 4503:

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

b) поочередно, если вы работаете под выделенным учетная запись службы (назовем ее "ServiceAccount" на домене "MyDomain"), то вы хотите

<identity>
     <userPrincipalName value="ServiceAccount@MyDomain" />
</identity>

обратите внимание, что вам может потребоваться использовать полное доменное имя в обоих случаях, включая уровни леса и дерева. Для простого домена внутри вашей частной LAN / WAN это будет означать адрес.Мойдомен.локальный и ServiceAccount@MyDomain.местный. Если ваш домен находится в дереве с именем MyTree, то это будет ServiceAccount@MyDomain.MyTree.местный; если это в лесу под названием MyForest тогда это будет Serviceaccount@MyDomain.MyTree.MyForest.локальный (и аналогичный для ServicePrincipalName). Необходимо полное имя при использовании Kerberos для проверки подлинности.


существует также грязный хак, как опубликовано здесь, здесь и здесь, и проанализировали!--10-->здесь.

можно указать фиктивное имя участника-службы (SPN). В этом случае WCF не потерпит неудачу, Но вернемся к NTLM для аутентификации, которая не проверяет принципала.

Итак, конфигурация:

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

и программно

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

используя Фабрики channelfactory:

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

также будет работать.