Let me first state that this question is awfully similar to the following post: MSMQ messages received but not delivered Windows 2008 R2. Still, the post is unclear about what resolved the problem.
I have two entities A and B both acting as services and clients to each other. I also have another entity C, which acts as a client to B.
All messages are sent on transacted queues. When I'm running the above scenario solely on localhost (Windows 7 professional), everything is fine: all messages are correctly sent and received.
Now the problem arises in the following setup where A and C are on my Windows 7 pro. machine and B is on a Windows Server 2012 R2.
For step 1 and 2, everything is sound: messages are sent and received. Now in 3, when B sends it's message to A, A never gets the message. MSMQ's events log tells me that B has indeed sent the message while A's last event is: "Message came over network".
When I check in the Transacted Dead Letter queue on B, I can now see that all my messages have the "invalid signature" error. From what I gathered, it seems that this error might be linked to authentification issues so here's what I've done in A's config:
<?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>
I also create the queue as follows:
MessageQueue queue;
if (!MessageQueue.Exists(queueName))
{
queue = MessageQueue.Create(queueName, true);
queue.Authenticate = false;
queue.SetPermissions("ANONYMOUS LOGON",
MessageQueueAccessRights.FullControl,
AccessControlEntryType.Allow);
}
Yet, still having the "invalid signature" issue. If anyone can shed some light on this,
many, many thanks in advance!
Found the solution. Most posts talking about the "invalid signature" error in the transacted dead letter queue explain in more or less details how it usually concerns a permission problem on the receiving end (in this case, the security configuration of A's queue). In my case, the problem lied on the sending end as well. Namely:
If you're getting "The signature is invalid" errors, that means your channel is trying to send authenticated messages.
For the sake of completeness, here is my current security configuration for A:
<netMsmqBinding>
<binding name="TransactedBinding" deadLetterQueue="System" useActiveDirectory ="False">
<security mode="None">
<message clientCredentialType="None"/>
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
</security>
</binding>
</netMsmqBinding>
A's service endpoint refers to this binding using:
<endpoint address="net.msmq://localhost/private/MainOrchestrator/MainOrchestratorService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.Contracts.OrchestratorContracts.IOrchestratorService" />
While this is all fine and dandy, it is not sufficient.
On B's side, I was sending the messages to a with:
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();
The problem lied in the NetMsmqBinding. By default, it seems that this binding tries to use authentication and this is why it failed. Replacing:
NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
with:
NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(NetMsmqSecurityMode.None);
Fixed the issue.