Ошибки недопустимой подписи MSMQ в очереди обработанных недоставленных сообщений

Позвольте мне сначала заявить, что этот вопрос ужасно похож на следующий пост: Сообщения MSMQ получены, но не доставлены Windows 2008 R2. Тем не менее, в сообщении неясно, что решило проблему.

Мой сценарий:

У меня есть две организации A и B, которые действуют друг для друга как услуги и клиенты. У меня также есть еще один объект C, который действует как клиент B.

  1. A отправляет сообщение B, регистрируя его URI.
  2. В случае какого-то события C отправляет сообщение B.
  3. Получив сообщение от C, B отправляет сообщение A.

Все сообщения отправляются в очереди транзакций. Когда я запускаю описанный выше сценарий исключительно на локальном хосте (Windows 7 Professional), все в порядке: все сообщения отправляются и принимаются правильно.

Теперь проблема возникает в следующей настройке, где A и C находятся в моей Windows 7 pro. машина, а B - на Windows Server 2012 R2.

На шагах 1 и 2 все в порядке: сообщения отправляются и принимаются. Теперь в 3, когда B отправляет сообщение A, A никогда не получает сообщение. Журнал событий MSMQ сообщает мне, что B действительно отправил сообщение, в то время как последнее событие A: «Сообщение пришло по сети».

Когда я проверяю очередь обработанных мертвых писем на B, я вижу, что все мои сообщения содержат ошибку «недействительная подпись». Из того, что я собрал, похоже, что эта ошибка может быть связана с проблемами аутентификации, поэтому вот что я сделал в конфигурации A:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <appSettings>
    <!-- use appSetting to configure MSMQ queue name -->
    <add key="queueName" value=".\private$\MainOrchestrator/MainOrchestratorService" />
    <add key="ClientSettingsProvider.ServiceUri" value="" />
  </appSettings>
  <system.serviceModel>
    <services>
      <service name="MachineCommunication.Orchestrators.MainOrchestrator.MainService" behaviorConfiguration="DefaultBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:13000/" />
          </baseAddresses>
        </host>
        <!-- Define NetMsmqEndpoint -->
        <endpoint address="net.msmq://localhost/private/MainOrchestrator/MainOrchestratorService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.Contracts.OrchestratorContracts.IOrchestratorService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <client>
      <endpoint address="net.msmq://windowsserver2012address/private/Zeiss/ZeissAdapterService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="IAdapterService" name="ZeissAdapter" />
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="DefaultBehavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netMsmqBinding>
        <binding name="TransactedBinding" deadLetterQueue="System" useActiveDirectory ="False">
          <security mode="None">
            <message clientCredentialType="None"/>            
            <transport msmqAuthenticationMode="None" msmqProtectionLevel="None"  />
          </security>          
        </binding>
      </netMsmqBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Я также создаю очередь следующим образом:

    MessageQueue queue;

    if (!MessageQueue.Exists(queueName))
    {
        queue = MessageQueue.Create(queueName, true);
        queue.Authenticate = false;

        queue.SetPermissions("ANONYMOUS LOGON",
            MessageQueueAccessRights.FullControl,
            AccessControlEntryType.Allow);
    }

Тем не менее, проблема с "недействительной подписью" все еще сохраняется. Если кто-то может пролить свет на это,

большое, большое спасибо заранее!


person Strav    schedule 26.08.2014    source источник


Ответы (2)


Нашел решение. Большинство сообщений, в которых говорится об ошибке «недействительной подписи» в очереди обработанных недоставленных сообщений, более или менее подробно объясняют, как это обычно связано с проблемой разрешения на принимающей стороне (в данном случае, с конфигурацией безопасности очереди A). В моем случае проблема также заключалась в отправляющей стороне. А именно:

Если вы получаете сообщение об ошибке «Подпись недействительна», это означает, что ваш канал пытается отправлять аутентифицированные сообщения.

(источник)

Для полноты, вот моя текущая конфигурация безопасности для A:

      <netMsmqBinding>
        <binding name="TransactedBinding" deadLetterQueue="System" useActiveDirectory ="False">
          <security mode="None">
            <message clientCredentialType="None"/>            
            <transport msmqAuthenticationMode="None" msmqProtectionLevel="None"  />
          </security>          
        </binding>
      </netMsmqBinding>

Конечная точка службы A обращается к этой привязке, используя:

<endpoint address="net.msmq://localhost/private/MainOrchestrator/MainOrchestratorService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.Contracts.OrchestratorContracts.IOrchestratorService" />

Хотя это все нормально, но этого недостаточно.

На стороне B я отправлял сообщения a с помощью:

            NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
            EndpointAddress epAddr = new EndpointAddress(client.clientUri);
            OrchestratorServiceClient orchestratorServiceClient = new OrchestratorServiceClient(msmqCallbackBinding, epAddr);                    

            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                sendAction(orchestratorServiceClient);
                scope.Complete();
            }
            orchestratorServiceClient.Close();

Проблема заключалась в NetMsmqBinding. По умолчанию кажется, что эта привязка пытается использовать аутентификацию, и поэтому она не удалась. Замена:

NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();

с участием:

NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(NetMsmqSecurityMode.None);

Проблема исправлена ​​.

person Strav    schedule 26.08.2014

Я пытался добавить комментарий, но мне не хватает «репутации». Это не совсем ответ, но я считаю, что ваша проблема связана с MSDTC.

person Ottak    schedule 26.08.2014
comment
Я не очень хорошо знаком с MSDTC; что заставляет вас думать, что это может быть связано с моей проблемой? Еще лучше: могу ли я убедиться, что это действительно связано? (и спасибо за ваш комментарий, кстати!) - person Strav; 26.08.2014
comment
Если вы подключаете более одного компьютера, необходимо задействовать координатора распределенных транзакций. Вы упомянули транзакционный MSMQ в отличие от нетранзакционных Q. см. этот пост как начало - person Ottak; 26.08.2014