简体   繁体   English

使用带有 Azure 服务总线和 MSI 身份验证的 MassTransit 出现 RBAC 问题

[英]RBAC issues using MassTransit with Azure service bus and MSI authentication

We are using MassTransit (v.5.5.5) with Azure Service Bus in a .net core v.2.2 application running in a container within Kubernetes.我们在 .net 核心 v.2.2 应用程序中使用带有 Azure 服务总线的 MassTransit (v.5.5.5),该应用程序在 Z30136395F01879792198317C1181 中的容器中运行。 During the Bus setup we create a token using the managed service identity (MSI), like this...在总线设置期间,我们使用托管服务标识 (MSI) 创建令牌,如下所示...

var tokenProvider = TokenProvider.CreateManagedServiceIdentityTokenProvider();
var busControl = Bus.Factory.CreateUsingAzureServiceBus(cfg =>
{
    IServiceBusHost busHost = cfg.Host(new Uri(Settings.Host), h =>
    {
        h.OperationTimeout = TimeSpan.FromSeconds(5);
        h.TokenProvider = tokenProvider;
        h.TransportType = Settings.TransportType;
    });
    ...
}

Within Azure, the MSI is configured with all 3 Service Bus permissions (Owner, Sender and Receiver) - as decribed here .在 Azure 中,MSI 配置有所有 3 个服务总线权限(所有者、发送者和接收者) - 如此所述。

When the application starts authentication seems to happen successfully but when MassTransit begins to listen on the specific queues we create it fails with the following error:当应用程序启动身份验证似乎成功,但是当 MassTransit 开始侦听我们创建的特定队列时,它失败并出现以下错误:

MassTransit.Azure.ServiceBus.Core.Transport.ReceiveTransport Error: 0 :
ReceiveTransport Faulted: sb://hostname.servicebus.windows.net/some-custom-queue, 
Microsoft.Azure.ServiceBus.UnauthorizedException: Generic: Failed during RBAC check, 
please make sure service resource provider is registered on your tenant.

Points to note:注意事项:

  • The application does create the temporary bus queue, and there are no errors to do with accessing it.应用程序确实创建了临时总线队列,访问它没有错误。
  • The application does not create our custom queues.该应用程序不会创建我们的自定义队列。
  • If the MSI permissions are removed then no queues are created and the error is different: Authorization failed for specified action: Manage,EntityWrite.如果 MSI 权限被删除,则不会创建队列并且错误不同: Authorization failed for specified action: Manage,EntityWrite.
  • For what it's worth we are using the AmqpWebSockets transport type.值得我们使用 AmqpWebSockets 传输类型。

It seems weird that the temporary queue is created but not our application-specific ones.创建临时队列而不是我们特定于应用程序的队列似乎很奇怪。

So I guess my question is this... have I done anything wrong or is this something that is not yet available for MassTransit using Service Bus with MSI?所以我想我的问题是……我做错了什么,或者这对于使用带有 MSI 的服务总线的 MassTransit 来说还没有?

Thanks in advance.提前致谢。

We came across the same issue.我们遇到了同样的问题。 We are using Mass Transit 6.* and Azure Service Bus.我们正在使用 Mass Transit 6.* 和 Azure 服务总线。 When switched to MSI we start see the same error:当切换到 MSI 时,我们开始看到相同的错误:

Microsoft.Azure.ServiceBus.UnauthorizedException: Generic: Failed during RBAC check, please make sure service resource provider is registered on your tenant. TrackingId:2644d62a-83a9-444f-8aeb-b4bdee2fa84d_G30, SystemTracker:NoSystemTracker, Timestamp:2020-02-13T15:54:49
    at Microsoft.Azure.ServiceBus.Management.ManagementClient.SendHttpRequest(HttpRequestMessage request, CancellationToken cancellationToken)
    at Microsoft.Azure.ServiceBus.Management.ManagementClient.PutEntity(String path, String requestBody, Boolean isUpdate, String forwardTo, String fwdDeadLetterTo, CancellationToken cancellationToken)
    at Microsoft.Azure.ServiceBus.Management.ManagementClient.CreateTopicAsync(TopicDescription topicDescription, CancellationToken cancellationToken)
    at MassTransit.Azure.ServiceBus.Core.Contexts.NamespaceManager.<>c__DisplayClass25_0`1.<<RunOperation>b__0>d.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at Microsoft.Azure.ServiceBus.RetryPolicy.RunOperation(Func`1 operation, TimeSpan operationTimeout)
    at Microsoft.Azure.ServiceBus.RetryPolicy.RunOperation(Func`1 operation, TimeSpan operationTimeout)
    at MassTransit.Azure.ServiceBus.Core.Contexts.NamespaceManager.RunOperation[T](Func`1 operation)
    at MassTransit.Azure.ServiceBus.Core.Contexts.ServiceBusNamespaceContext.CreateTopic(TopicDescription topicDescription)
    at MassTransit.Azure.ServiceBus.Core.Pipeline.ConfigureTopologyFilter`1.ConfigureTopology(NamespaceContext context)
    at MassTransit.Azure.ServiceBus.Core.Pipeline.ConfigureTopologyFilter`1.<>c__DisplayClass5_0.<<Send>b__0>d.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at GreenPipes.PipeExtensions.OneTimeSetup[T](PipeContext context, Func`2 setupMethod, PayloadFactory`1 payloadFactory)
    at MassTransit.Azure.ServiceBus.Core.Pipeline.ConfigureTopologyFilter`1.Send(NamespaceContext context, IPipe`1 next)
    at GreenPipes.Agents.AsyncPipeContextPipe`1.Send(TContext context)
    at GreenPipes.Agents.PipeContextSupervisor`1.GreenPipes.IPipeContextSource<TContext>.Send(IPipe`1 pipe, CancellationToken cancellationToken)
    at GreenPipes.Agents.PipeContextSupervisor`1.GreenPipes.IPipeContextSource<TContext>.Send(IPipe`1 pipe, CancellationToken cancellationToken)
    at GreenPipes.Agents.PipeContextSupervisor`1.GreenPipes.IPipeContextSource<TContext>.Send(IPipe`1 pipe, CancellationToken cancellationToken)
    at MassTransit.Azure.ServiceBus.Core.Pipeline.JoinContextFactory`3.<>c__DisplayClass7_0.<<CreateJoinContext>g__Join|0>d.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at MassTransit.Azure.ServiceBus.Core.Pipeline.ClientContextFactory.CreateSharedContext(Task`1 context, CancellationToken cancellationToken)
    at GreenPipes.Agents.PipeContextSupervisor`1.GreenPipes.IPipeContextSource<TContext>.Send(IPipe`1 pipe, CancellationToken cancellationToken)
    at GreenPipes.Agents.PipeContextSupervisor`1.GreenPipes.IPipeContextSource<TContext>.Send(IPipe`1 pipe, CancellationToken cancellationToken)
    at GreenPipes.Agents.PipeContextSupervisor`1.GreenPipes.IPipeContextSource<TContext>.Send(IPipe`1 pipe, CancellationToken cancellationToken)
    at MassTransit.Azure.ServiceBus.Core.Transport.ReceiveTransport.<Receiver>b__12_0()
    at MassTransit.Azure.ServiceBus.Core.Pipeline.JoinContextFactory`3.<>c__DisplayClass7_0.<<CreateJoinContext>g__Join|0>d.MoveNext()

Finally we found that ASB Sdk Microsoft.Azure.ServiceBus.Management.ManagementClient doesn't allow to create topics with slashes in path when tokens from MSI used.最后我们发现 ASB Sdk Microsoft.Azure.ServiceBus.Management.ManagementClient不允许在使用来自 MSI 的令牌时在路径中创建带有斜杠的主题。 This code below return the same error:下面的代码返回相同的错误:

         try
            {
                var address = "sb://[name].servicebus.windows.net";
                var tokenProvider = new TokenProvider.CreateManagedIdentityTokenProvider();();
                var _managementClient = new ManagementClient(address.ToString(), tokenProvider);
                var topicDefinition = new TopicDescription("myNewTopic/22222");
                await _managementClient.CreateTopicAsync(topicDefinition);

            }
            catch (Exception e)
            {
                Debug.WriteLine(e);

                throw;
            }

Since MT uses special naming convention to setup messaging topology, we get topic path with namespace of particular message type.由于 MT 使用特殊的命名约定来设置消息拓扑,我们得到具有特定消息类型命名空间的主题路径。 If we have message MassTransitTest.Message1 it will be converted to topic MassTransitTest/Message1 (with slash).如果我们有消息MassTransitTest.Message1 ,它将被转换为主题MassTransitTest/Message1 (带有斜线)。 To fix this we setup our own IEntityNameFormatter为了解决这个问题,我们设置了我们自己的IEntityNameFormatter

public class MyEntityNameFormatter : IEntityNameFormatter
{
    readonly IMessageNameFormatter _formatter;

    public MyEntityNameFormatter()
    {
        _formatter = new ServiceBusMessageNameFormatter();
    }
    public string FormatEntityName<T>()
    {
        var entityName = _formatter.GetMessageName(typeof(T)).ToString().Replace("/",".");
        return entityName;
    }
}

and then接着

 var bus = Bus.Factory.CreateUsingAzureServiceBus(configurator =>
            {
                ...
                configurator.MessageTopology.SetEntityNameFormatter(new MyEntityNameFormatter());
                ...

This fixed our issue.这解决了我们的问题。 (We tried use ~ instead of. but got some validation errors, so decided use dots) (我们尝试使用 ~ 代替。但有一些验证错误,所以决定使用点)

I have been able to reproduce the same error using Azure Service Bus SDK code directly in a .NET Core (3.0) ASP.NET application hosted in an AppService with Managed Identity. I have been able to reproduce the same error using Azure Service Bus SDK code directly in a .NET Core (3.0) ASP.NET application hosted in an AppService with Managed Identity.

string serviceBusNamespace = "busnamespace_here";

string queueName = "with_service_name/test"; // NOT working with RBAC
// string queueName = "testrbac"; // Works with RBAC - no /

var msiTokenProvider = TokenProvider.CreateManagedIdentityTokenProvider();
var qc = new QueueClient(new Uri($"sb://{serviceBusNamespace}.servicebus.windows.net/").ToString(), queueName, msiTokenProvider);

var message = new Message(Encoding.UTF8.GetBytes($"Test {DateTime.Now.ToShortTimeString()}"))
{
    ContentType = "application/text",
    Label = "Scientist",
    MessageId = Guid.NewGuid().ToString()
};

try
{
    await qc.SendAsync(message);
}
catch (Exception ex)
{
    return View(ex.ToString());
}

I found out that the error seems to be caused by the presence of a / in the queue name.我发现该错误似乎是由于队列名称中存在 / 引起的。 It's a character that is allowed in the Service Bus but it doesn't seems to works quite nicely with RBAC Service Bus feature.它是服务总线中允许使用的字符,但它似乎不能很好地与 RBAC 服务总线功能配合使用。
The same code works well if you use a SAS Policy instead of Managed Identity/Client Secret.如果您使用 SAS 策略而不是托管身份/客户端密码,则相同的代码效果很好。

Here is my test Service Bus in image (using Service Bus Explorer):这是我在图像中的测试服务总线(使用服务总线资源管理器):

服务总线拓扑

Mass Transit轨道交通

I know Mass Transit can use entity path with slash character in it.我知道 Mass Transit 可以使用带有斜线字符的实体路径。 Does that means we can't use RBAC to access those entities?这是否意味着我们不能使用 RBAC 来访问这些实体?

I wasn't able to find what is the root cause.我无法找到根本原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 RBAC 连接到 Azure 服务总线停止工作 - Connect to Azure Service Bus using RBAC stopped working 我可以使用 RBAC 访问 Azure 服务总线继电器吗? - Can I Access Azure Service Bus Relay Using RBAC? Azure 服务总线性能问题 MassTransit - Azure Service Bus performance issue MassTransit Azure Service Bus上的MassTransit抛出MessageSizeExceededException - MassTransit on Azure Service Bus throws MessageSizeExceededException 使用Azure Service Bus创建队列的MassTransit 3 - MassTransit 3 with Azure Service Bus creating queues MassTransit Azure 服务总线日志级别 - MassTransit Azure Service Bus log level Azure 服务总线和公共交通,相同的消息,不同的命名空间 - Azure service bus and masstransit, same message, different namespace 是否可以在没有管理权限策略的情况下将 MassTransit 3 与 Azure 服务总线一起使用? - Is it possible to use MassTransit 3 with Azure Service Bus without Manage permission policy? 使用大众运输向天蓝色服务总线主题中的特定订户组发送消息 - Sending message to a specific group of subscriber in azure service bus topic with masstransit MassTransit Azure 总线 PrefetchCount 必须为 1 - MassTransit Azure bus PrefetchCount must be 1
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM