问题
I spent some days testing MassTransit 3.1.2 to see if we can use it with Azure Service Bus in our applications.
I made a sample with two console applications using MassTransit.AzureServiceBus (3.1.2) : one publisher and one suscriber.
It works well. When I start the applications, the entities (queues, topic, subscriptions) are created automatically on my namespace on Azure.
That's nice when you are testing thing but in production, I don't want the application to be allowed to create entities. We want to create them upfront.
To try that, I thought It was a good idea to connect to the bus using SAS policy with "Send" or "Listen" permissions only (before I was using a namespace policy with "Manage" permission).
Now I'm struggling on this point, I can't get it to work, I'm always getting 401 errors Manage claim is required for this operation if I don't use a policy with "Manage" permissions.
I tried setting the policy on the namespace or the entities directly without success.
After that I analyzed the stack trace exception (useless part omitted with [...]) :
System.UnauthorizedAccessException: Le serveur distant a retourné une erreur : (401) Non autorisé. Manage claim is required for this operation. TrackingId:2ca420e3-aac6-467c-bacb-6e051dbc3e39_G47,TimeStamp:1/29/2016 11:20:41 PM ---> System.Net.WebException: Le serveur distant a retourné une erreur : (401) Non autorisé.
à System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
à Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.GetAsyncResult`1.<GetAsyncSteps>b__3c(GetAsyncResult`1 thisPtr, IAsyncResult r)
à Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
--- Fin de la trace de la pile d'exception interne ---
Server stack trace:
Exception rethrown at [0]:
à Microsoft.ServiceBus.Common.ExceptionDispatcher.Throw(Exception exception)
à Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
à Microsoft.ServiceBus.Common.AsyncResult`1.End(IAsyncResult asyncResult)
à Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.EndGet[TEntityDescription](IAsyncResult asyncResult, String[]& resourceNames)
à Microsoft.ServiceBus.NamespaceManager.EndGetQueue(IAsyncResult result)
à System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.AzureServiceBusTransport.NamespaceManagerExtensions.<CreateQueueSafeAsync>d__1.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.AzureServiceBusTransport.Pipeline.PrepareReceiveQueueFilter.<Send>d__5.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.AzureServiceBusTransport.ServiceBusReceiveTransport.<>c__DisplayClass12_0.<<Receiver>b__0>d.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.Internals.Extensions.TaskExtensions.<WithCancellation>d__0`1.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception
[...]
à MassTransit.MassTransitBus.<StartAsync>d__30.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
à System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
à MassTransit.MassTransitBus.<StartAsync>d__30.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
à System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
à MassTransit.Util.TaskUtil.Await[T](Func`1 taskFactory, CancellationToken cancellationToken)
à MassTransit.MassTransitBus.MassTransit.IBusControl.Start()
I found out that the line with MassTransit.AzureServiceBusTransport.NamespaceManagerExtensions.CreateQueueSafeAsync to be really interesting because I was able to look at the MassTransit source code to see what it was doing. I saw that it was doing some calls using the NamespaceManager to get the queue or topic.
Since this class is named NamespaceManager, I thought that would mean you need "Manage" permission anyway.
To try that, I made a basic console application using only the Azure SDK to make some calls to the NamespaceManager using a policy with only Listen or Send permissions : I got 401 errors on all the calls I tried. Adding Manage permission worked.
I didn't find anything about this assumption in the Azure documentation or maybe I missed something.
Final question :
Is there a way to use MassTransit on Azure Service Bus with a Send or Listen policy only ? Did I miss something and I'm heading the wrong way ?
回答1:
Because MassTransit is responsible for managing the topology of the service bus namespace, including creating topics and queues as well as creating and binding subscriptions, the manage permission is required.
While you might think it's a great idea to create everything in production manually and leave that permission off your application, you will always spend time figuring out why things are broken in production and frustrate your engineers. I speak from experience on this one -- it's why we require the permission.
There are also auto-delete queues created for bus management, which again requires the manage permission.
来源:https://stackoverflow.com/questions/35096497/is-it-possible-to-use-masstransit-3-with-azure-service-bus-without-manage-permis