Azure Durable functions: How to use ManagedIdentity connection in ServiceBusTrigger

83 Views Asked by At

I have a .Net8 dotnet-isolated Azure Durable Functions project. I'm using a ServiceBusTrigger to get the messages from a service bus queue:

    [Function(nameof(Function1))]
public async Task Run(
    [ServiceBusTrigger("some-queue-name", Connection = "ServiceBus")]
    ServiceBusReceivedMessage message,
    ServiceBusMessageActions messageActions)
{
    _logger.LogInformation("Message ID: {id}", message.MessageId);
    _logger.LogInformation("Message Body: {body}", message.Body);
    _logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);

    // Complete the message
    await messageActions.CompleteMessageAsync(message);
}

In the local.settings.json file there are settings for the service bus connection:

"ServiceBus:fullyQualifiedNamespace": "****.servicebus.windows.net",
"ServiceBus:tenantId": "***************",
"ServiceBus:clientId": "***************",
"ServiceBus:clientSecret": "***************"

In this way, the ServiceBus trigger function can connect and receive messages from the Service Bus.

However, I want to connect to the service bus without specifying the client secret, just using the token credential or any other way it works.

When in Program.cs I specify

services.AddAzureClients(builder =>
{
    var managedIdentityCredential = new ManagedIdentityCredential(azureClientId);

    builder
        .AddServiceBusClient("******.servicebus.windows.net")
        .WithCredential(managedIdentityCredential);
});

I cannot connect to the service bus, there are exceptions:

[2024-02-16T14:12:42.315Z] System.Private.CoreLib: Unauthorized access. 'Listen' claim(s) are required to perform this operation. Resource: 'sb://****.servicebus.windows.net/{queue-name}'. TrackingId:, SystemTracker:*****, Timestamp:2024-02-16T14:13:01

When I change the settings in local.settings.json like Microsoft guide says,

"ServiceBus:credential": "managedidentity",
"ServiceBus:clientId": "*******",

The app starts without any errors, but cannot receive any messages from the Service Bus queue. The same story if I use managedIdentityResourceId

"ServiceBus:credential": "managedidentity",
"ServiceBus:managedIdentityResourceId": "/subscriptions/************/resourceGroups/Default-ServiceBus-WestEurope/providers/Microsoft.ServiceBus/namespaces/********"

Still no errors, but no messages received.

But with the client secret specified in the local settings, it works. The client has all the required roles for Service bus messages sending/receiving.

So how to receive messages from the service bus queue using ServiceBusTrigger and ManagedIdentity?

1

There are 1 best solutions below

0
RithwikBojja On

AFAIK and according to SO-Thread, in Local machine Managed identity usage is not possible. But you can use Managed identity and can do the same in Portal follow below process:

Create a function app and service bus queue trigger In local:

Function.cs:

using System;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace FunctionApp124
{
    public class Function1
    {
        private readonly ILogger<Function1> _logger;

        public Function1(ILogger<Function1> logger)
        {
            _logger = logger;
        }

        [Function(nameof(Function1))]
        public async Task Run(
            [ServiceBusTrigger("myqueue", Connection = "rithcon")]
            ServiceBusReceivedMessage message,
            ServiceBusMessageActions messageActions)
        {
            _logger.LogInformation("Message ID: {id}", message.MessageId);
            _logger.LogInformation("Message Body: {body}", message.Body);
            _logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);

            // Complete the message
            await messageActions.CompleteMessageAsync(message);
        }
    }
}

local.settings.json:

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
        "rithcon__fullyQualifiedNamespace":"rith75.servicebus.windows.net"
    }
}

Program.cs:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

Create a Function app in Portal and, Then On Managed Identity In azure function:

enter image description here

Now deploy the function to portal.

Then give role Azure Service Bus Data Receiver to Managed Identity in Service bus:

enter image description here

In Environment variables section add:

enter image description here

Output:

Then it worked like below:

enter image description here