NServiceBus: ASP.NET Permissions for MSMQ

I have two different development machines, one at home and one at work. I'm definitely not a laptop guy because I like having three monitors. In any case, this gives me the ability to develop slightly different environments which helps uncover subtle issues. One such issue that I encountered was related to that of sending a message through NServiceBus to an endpoint inside of a web application.

On my home machine, everything was working great. But on my work machine, I spent the better part of a morning looking on Stack Overflow and other such websites and debugging the following exception thrown by the queuing infrastructure:

Access to Message Queuing system is denied.

Ultimately things boil down to permission issues, but there were a few subtle, and unexpected behaviors being exhibited by MSMQ. Normally when you are working with a regular application and you run into security issues, you can simply change the permissions and re-run the affected code and everything will work. Not so in ASP.NET. Once NServiceBus acquires a handle to the queuing infrastructure it will retain that handle and security context for the remainder of the application lifetime. Usually this isn't too much of a problem. But when you change permissions on a queue while NServiceBus has an open queue handle, the changed permissions don't seem to propagate to the handle. Knowing this would have saved me a significant amount of time.

Further, NServiceBus likes each web application to have an "input queue". But if you are sending a message to another local queue that is *not* the input queue, e.g. it's your domain input queue or back-end processing input queue, MSMQ appears to send directly to that queue instead of going through the input queue. What this means is that you have to correctly set permission on *both* queues! Yuck. I'll elaborate my finds regarding those permissions momentarily.

Normally permissions issues can be debugged by setting Everyone to "Full Control" and going back from there. And this case is no different, but only when you understand that the queue handle held by NServiceBus isn't affected by permission changes, so the app needs to be recycled, which can be as simple as modifying the web.config, and only if you understand that you may have to adjust permissions on several queues.

Here is what I found regarding permissions. There are two critical permission required to send to a queue—these two permissions alone can avoid the "Access to Message Queuing system is denied." They are: "Get Properties" (which is the most surprising) and, of course, Send Message.

permissions2 permissions1

From there you'll want to configure at least the two permissions above as well as "Peek Message" and "Receive Message".

But this is only half of the story. Once we can talk to the infrastructure, we need to do so under the appropriate credentials. In IIS 6, you typically will use NETWORK SERVICE. Under IIS 7 and 7.5, you'll typically want to use: "ApplicationPoolIdentity". This creates a well-named system "sub-account" of sorts that you can reference in your permissions. Just add something like this: IIS AppPoolName_Of_My_Application_Pool.