没有“管理”权限策略的情况下,是否可以将MassTransit 3与Azure Service Bus一起使用?

Céd*_*c V 5 c# masstransit azure azureservicebus

我花了几天时间测试MassTransit 3.1.2,以查看是否可以在应用程序中将它与Azure Service Bus一起使用。

我使用MassTransit.AzureServiceBus(3.1.2)通过两个控制台应用程序制作了一个示例:一个发布者和一个订阅者。

它运作良好。当我启动应用程序时,实体(队列,主题,订阅)将自动在Azure上的命名空间上创建。
当您测试事物但在生产中时,这很好,我不希望该应用程序被允许创建实体。我们想预先创建它们。

为此,我认为使用仅具有“发送”“监听”权限的SAS策略连接到总线是一个好主意(在使用具有“管理”权限的名称空间策略之前)。

现在,我在这一点上苦苦挣扎,无法正常工作,总是遇到401错误如果我不使用具有“管理”权限的策略,则必须对此操作要求管理声明
我尝试直接在名称空间或实体上设置策略,但没有成功。

之后,我分析了堆栈跟踪异常(用[...]省略了无用的部分):

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()
Run Code Online (Sandbox Code Playgroud)

我发现与MassTransit.AzureServiceBusTransport.NamespaceManagerExtensions.CreateQueueSafeAsync在一起的行非常有趣,因为我能够查看MassTransit源代码以查看其作用。我看到它正在使用NamespaceManager进行一些调用以获取队列或主题。

由于该类名为NamespaceManager,因此我认为那将意味着您仍然需要“ 管理 ”权限。
为此,我仅使用Azure SDK制作了一个基本的控制台应用程序,使用仅具有“侦听”或“发送”权限的策略对NamespaceManager进行了一些调用:在所有尝试的调用上都出现401错误。添加“管理”权限有效。

我在Azure文档中没有找到关于此假设的任何信息,或者我错过了一些东西。

最后一个问题:

是否可以仅在Azure Service Bus上使用“发送”或“侦听”策略来使用MassTransit?我错过了什么吗?我走错了路吗?

Chr*_*son 5

由于 MassTransit 负责管理服务总线命名空间的拓扑,包括创建主题和队列以及创建和绑定订阅,因此需要管理权限。

虽然您可能认为在生产中手动创建所有内容并将该权限关闭应用程序是一个好主意,但您总是会花时间弄清楚为什么在生产中出现问题并使您的工程师感到沮丧。我是根据经验谈这个问题的——这就是我们需要许可的原因。

还有为总线管理创建的自动删除队列,这也需要管理权限。

更新:仍然需要管理,但是,您可以绕过它。如果您可以提前创建主题、队列和订阅,并且您将 MassTransit 配置为不创建主题、队列或订阅,并且可能不发布故障(除非您也打算创建这些主题),并且不使用错误或跳过队列。

例如,此配置基本上将 MassTransit 的使用限制为仅用于队列:

var bus = Bus.Factory.CreateUsingAzureServiceBus(cfg =>
{
    cfg.Host(...);

    cfg.ReceiveEndpoint("existing-queue", e =>
    {
        e.PublishFaults = false;
        e.ConfigureConsumeTopology = false;

        e.ConfigureDeadLetterQueueErrorTransport();
        e.ConfigureDeadLetterQueueDeadLetterTransport();

        e.Consumer(...);
    });
});
Run Code Online (Sandbox Code Playgroud)

直接发送到队列的消息(destinationAddress of queue:existing-queue)将由接收终结点使用,错误/跳过的消息将移动到 Azure 死信队列。如果存在与消息类型匹配的主题名称(或者您可以topic:existing-topic-name用作目标地址),则只能调用发布。

  • 当我阅读源代码时,我几乎可以肯定这一点,但由于我是 MassTransit 的新手,我想请教一下,谢谢 Chris 的澄清。由于需要此权限,例如,您将如何控制错误配置的应用程序不会与错误的队列混淆?良好的监控?你有任何关于这一点的资源吗?再次感谢您的回答! (3认同)
  • 对塞德里克的好问题也很感兴趣。这对于最新版本仍然有效吗?如果使用 Masstransit 的应用程序始终能够管理并因此读取和写入命名空间内的任何消息,人们如何限制权限? (3认同)
  • 这是一个好点。您是否找到了有关此主题的更多信息?我处于需要与我们不拥有的外部软件集成的情况,因此我不放心为他们提供具有管理权限的访问密钥。 (2认同)
  • 您能否添加一个代码片段来配置向现有主题发布(多种类型的消息)的应用程序?我已经创建了该主题(它是应用程序完全自动化部署的一部分),但应用程序仍然需要管理权限。我还没有找到一种方法来阻止 MassTransit 尝试部署(或以其他方式“管理”)拓扑。 (2认同)