This message could not be delivered because the user with ID [application user] in database ID [database] does not have permission to send to the service. Service name: SqlQueryNotificationService-[guid].
The problem is that [guid] is different each time, and there doesn't seem to be a generic "grant send on all services" statement, so I can't grant send on the particular service in question to the application user to get rid of the error. (If I grant db_owner to the application user, the problem goes away and everything works, but I'd rather not do that. The application user already has subscribe query notifications, receive on QueryNotificationErrorsQueue, and references on contract::...PostQueryNotification.)
Obviously I'm doing something wrong, but I am completely out of ideas and can't seem to find anything new to try. Any ideas? Thanks.
It is not clear to me how can an application separate the roles of creating the notification and getting the notification using SqlDependency (which is the component that creates the 'SqlQueryNotificationService-[guid]' named services). The SqlDependency is intended to be used by one appdomain that calls Start and then various callbacks (notification subscriptions) are being set up by the same appdomain.
Do you have a particular reason why you want to separate the two roles?
Utimately you can always go one level down and use the SqlNotification objects instead of SqlDependency. They are more primitive (no automated provisioning of a temp service/queue/procedure for each appdomain etc etc), but they allow more control as you can specify explicitly the service that is intended to receive the notifications and you can set up said service as your heart desires (including all the necessary GRANTs).
|||The reason for separating them is that the user starting the dependency has to have a bunch of create privileges in its default schema, and for security reasons we don't want the application user to have such access. By isolating the user doing the start in its own schema, we can keep the application user and the main schema locked down.It turns out that there is a solution, however... by Reflecting through the SqlDependency class, I determined that it's hard-wired to look for a role called "sql_dependency_subscriber", and if that role exists it grants the necessary privileges to it upon startup. By creating the role and adding the application user to it, everything works. Seems like a major kludge on Microsoft's part to me, and it would have helped if it was documented somewhere, but it does the trick nonetheless.
|||Well, that is news for me as well. I never knew SqlDependency does that.
No comments:
Post a Comment