Служба WCF как потребитель другой службы WCF

В обновляемом проекте я должен использовать службу WCF (Служба A), опубликованную третьей стороной (без контроля) в моей службе WCF. Я использую ServiceA в проекте My Web App (vs2008), и он работает нормально.

Я начал с добавления ссылки на службу в свой проект WCF (ServiceB). Допустим, название службы - «XYZ». VS создал все необходимые файлы, но когда я попытался скомпилировать, он дал ошибку

Имя типа «XYZ» не существует в типе «ServiceB.ServiceB»;

В моей "Service B" есть "ServiceB.SVC"

Я попытался решить эту проблему, удалив пространство имен «ServiceB». из файла Reference.cs и его содержимого. Затем этот код можно было скомпилировать.

Теперь я получаю исключение, что

«Вызывающий абонент не был аутентифицирован службой».

Внутреннее исключение

Запрос токена безопасности не может быть удовлетворен из-за сбоя аутентификации.

в System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault (сообщение сообщения, целевой адрес EndpointAddress) в System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody (сообщение incomingMessage, SspiNegotiationStateState

=>

((System.ServiceModel.FaultException) (ex.InnerException)). Сообщение Не удалось удовлетворить запрос токена безопасности из-за ошибки аутентификации.

Файл Web.Config на ServiceB выглядит следующим образом:

 <wsHttpBinding>
        <binding name="WSHttpBinding_IABCService" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
              algorithmSuite="Default" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://aaaaa/ ServiceA.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IABCService"
        contract="XYZ.IABCService" name="WSHttpBinding_IABCService">
        <identity>
          <servicePrincipalName value="host/[hostname]" />
        </identity>
      </endpoint>
    </client>

======

Я заставил себя поверить, что проблема может заключаться в доступе WCF к WCF. Я создал веб-службу (.asmx) и добавил ссылку на ServiceA. Когда я отлаживаю, вызывая метод, я получаю результаты от ServiceA. Надеясь, что это решение, которое я смогу использовать, пока не выясню между проблемами WCF и WCF, я добавил ссылку на службу asmx в свою службу WCF (ServiceB). Когда я отлаживаю, запустив ServiceB -> asmx -> Service A, я снова получаю ошибку аутентификации из-за ошибки пользователя !!!

Я считаю, что это как-то связано с выдачей личности за личность ...

Я читал, что ServiceB web.config имеет приоритет над asmx web.config, но я не смог найти решение.

Я не могу выключить «Security Mode = None», так как тогда служба A отвечает, говоря, что токены не были переданы.

Любая помощь будет принята с благодарностью: помните, что я могу использовать WC Service A из WebApp и из asmx, но не из другого WCF напрямую или косвенно.

Спасибо

Мар


person TheMar    schedule 25.06.2010    source источник


Ответы (3)


Это не имеет ничего общего с WCF, вызывающим WCF. Попробуйте представить, что вызов WCF вызывает ошибки компиляции - и что вы первый человек в мире, обнаруживший это с 2006 года!

Попытайтесь полностью определить тип «XYZ», указав полное пространство имен. Если это не сработает, щелкните правой кнопкой мыши ссылку на каждую службу и выберите «Просмотреть в обозревателе объектов». Посмотрите, каково полное название типов.

Если ничего из этого вам не помогает, публикуйте полные сообщения об ошибках и / или исключениях.

И, пожалуйста, не никогда редактировать Reference.cs. Любые ваши правки будут уничтожены при следующем выполнении «Справки по службе обновлений». Следовательно, любое изменение, которое, по вашему мнению, вы хотите внести в Reference.cs, можно сделать лучше, не меняя его, либо вы действительно не хотите вносить это изменение вообще (например, сделанное вами изменение).

person John Saunders    schedule 25.06.2010
comment
Спасибо, что предложили не изменять Reference.cs. Я просмотрел ссылку на службу в обозревателе объектов, и все выглядит нормально. Кажется, есть другие люди, у которых были подобные проблемы в (поиск в Интернете). Я исследую некоторые из их проблем, чтобы узнать, смогу ли я найти решение. Я пытался указать полное имя, но это не помогло. Я обновлю то, что найду, как только смогу подключиться к моей офисной системе. - person TheMar; 27.06.2010

Мне кажется, что вместо олицетворения нужно иметь делегацию. Чтобы преобразовать токен текущего пользователя в другой, вы можете использовать DuplicateToken DuplicateTokenEx (последний может производить TokenPrimary) с SecurityDelegation SecurityImpersonation (SECURITY_IMPERSONATION_LEVEL), а затем WindowsIdentity(IntPtr) конструктором. См. Пример LogonUser и делегирование.

Другой способ - это изменение протокола: S4U, S4U2Self (см. http://msdn.microsoft.com/en-us/magazine/cc163500.aspx, http://msdn.microsoft.com/en-us/library/ff650469.aspx, http://msdn.microsoft.com/en-us/library/ms998355.aspx). Вы можете использовать что-то вроде new WindowsIdentity(clientUPN).Impersonate().

person Oleg    schedule 25.06.2010
comment
Не могли бы вы ответить на stackoverflow.com/questions/9584198/ ? - person LCJ; 06.03.2012

Если вам нужно выполнить делегирование (т.е. действовать как исходный вызывающий), процесс подробно описан на эта ветка форума MSDN. Не используйте делегирование с полным доверием - для этого требуются права администратора для AD, и это не очень хорошо с точки зрения безопасности. Ограниченное делегирование легко настроить правильно, если вы знаете, какие имена использовать в команде SETSPN. Также убедитесь, что вы запускаете службу B (делегат), используя учетную запись пользователя домена, учетные записи компьютеров, такие как сетевая служба / локальная служба или учетные записи локальных пользователей, не будут работать, потому что вы не сможете создать для них SPN.

person seva titov    schedule 25.03.2011
comment
Не могли бы вы ответить на stackoverflow.com/questions/9584198/ ? - person LCJ; 06.03.2012