Java-приложение, вызывающее WCF, возвращает «Сброс подключения», в то время как SoapUI работает нормально - PullRequest
1 голос
/ 01 июня 2019

У меня есть приложение C # MVC (.NET Framework 4.6.2) с веб-службой WCF (на основе мыла), расположенной в / webservice внутри приложения. Веб-сервис WCF предназначен для стороннего поставщика, который может позвонить и отправить свои данные. У нас есть приложение в тестовой среде на сервере Windows Server 2016 с открытыми портами 80 и 443, и наши сертификаты не подписаны и не действительны. Когда мы тестируем сервис с помощью SoapUI, мы можем правильно получить доступ к веб-сервису WCF и опубликовать тестовые данные на сервере, но когда наш поставщик публикует данные из своего Java-приложения, он получает «Сброс подключения». Мы удалили всю аутентификацию и просто пытаемся заставить их добраться до WCF, но наши журналы IIS и журналы приложений даже не показывают, что они попадают на наш сервер. SoapUI (как внутри, так и за пределами нашей сети / брандмауэра) может правильно подключиться к сервису. Наш web.config выглядит так:

<system.serviceModel>
<diagnostics>
  <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="3000"/>
</diagnostics>
<bindings>
  <basicHttpBinding>
    <binding name="basicBinding" textEncoding="utf-8" openTimeout="00:03:00" closeTimeout="00:03:00"/>
  </basicHttpBinding>
</bindings>
<services>
  <service behaviorConfiguration="serviceBehavior" name="WebServiceUniqueName">
    <endpoint address="/endpoint/soap" binding="basicHttpBinding" bindingConfiguration="basicBinding" name="soapEndpoint" bindingNamespace="https://test.site.com/webservice" contract="Our.Namespace.ISoapContract"/>
    <endpoint address="mex" binding="mexHttpBinding" name="mexEndpoint" contract="IMetadataExchange"/>
    <host>
      <baseAddresses>
        <add baseAddress="/webservice/servicename"/>
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="serviceBehavior">
      <serviceMetadata externalMetadataLocation="https://test.site.com/webservice/content.xml"
        httpGetEnabled="true" />
      <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>

и код для нашего WCF выглядит так:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(Namespace = "https://test.site.com/webservice")]
public class MyService : ISoapContract
{
    public DataResponse SubmitData(DataRequest input)
    {
        // Code here
    }
}

namespace Our.Namespace
{
    [ServiceContract(Namespace = "https://test.site.com/webservice")]
    [XmlSerializerFormat]
    public interface ISoapContract
    {
        [OperationContract(Name = "SubmitData")]
        [XmlSerializerFormat]
        DataResponse SubmitData(DataRequest input);
    }
}

Наш сервер работает с TLS 1.2 и возвращается к 1.1 (именно то, что ожидает производитель). Наш брандмауэр не показывает ничего заблокированного, и в течение первых нескольких секунд после их запроса появляется сообщение «Сброс подключения». Сторонний разработчик может получить доступ к WSDL из своих браузеров, поэтому все это заставляет меня поверить, что во время рукопожатия происходит сбой. Выходит SoapUI, и он работает на Java, так что мы действительно озадачены этим моментом. Требует ли Java для вызова приложения C # WCF что-то дополнительное? Есть ли способ запечатлеть попытку рукопожатия?

Обновление после дополнительных испытаний:

Мы воспользовались советом Самбита и использовали клиент веб-службы Microsoft, и это сработало без проблем. Мы создали еще один тестовый WCF, а также создали приложение, которое называется наш сервер и помещает оба в Azure без каких-либо проблем. Мы могли бы связаться с нашим веб-сервисом, но поставщик все еще не может связаться с сервером. Мы добавили дополнительное ведение журнала и посмотрели на брандмауэр, и трафик от поставщика проходил через брандмауэр и на сервер, но сообщал о «сбросе TCP с сервера».

Приложение стороннего поставщика было размещено в общей среде, и они могут запускать команды на своем сервере, но не могут изменить какой-либо код для регистрации дополнительной информации. Они смогли пропинговать наш сервер и выполнить следующую команду:

nc -zv (server_url) 443

И это успешно подключилось, но когда они попытались получить сертификат от сервера, это не удалось:

openssl s_client -tls1_2 -showcerts -connect (server_url): 443

СОЕДИНЕНО (00000003) запись: errno = 104

--- нет сертификата пира

--- Имена CA сертификатов клиентов не отправлены

1 Ответ

1 голос
/ 18 июня 2019

После помощи множества действительно умных людей с обеих сторон проблема закончилась тем, что указывалось имя сервера (SNI):

https://en.wikipedia.org/wiki/Server_Name_Indication

В приложении поставщика запущена стараяверсия Java, которая не понимает / не поддерживает SNI и не может обновиться в настоящее время.

Администраторы нашего сервера выделили IP на нашем Windows Server для домена, вызываемого поставщиком, и отключили SNIдля этого конкретного домена.Теперь мы можем принимать вызовы веб-сервера поставщика без каких-либо проблем.

...