2

I'm migrating a servicebus client application from Microsoft.Azure.ServiceBus to use the current library Azure.Messaging.ServiceBus.

The application is a Worker Process running on a virtual machine in windows azure.

The VM has a system assigned managed identity which grants it access to service bus and we have been using it successfully with the old library for over a year.

On the old library we created a client using this connection string

Endpoint=sb://MyNamespace.servicebus.windows.net/;Authentication=Managed Identity

When I put that connection string into the constructor of Azure.Messaging.ServiceBus.ServiceBusClient I get the following error

The connection string used for an Service Bus client must specify the Service Bus namespace host and either a Shared Access Key (both the name and value) OR a Shared Access Signature to be valid. (Parameter 'connectionString')

I've been trawling through documents for some time now with no progress. Is there anyway to make this work?

Ideally I would continue to use the connection string - developer machines do not have system assigned ID's so we develop with key based connection strings and let devops swap in the correct prod connection string.

UPDATE

Following on from Jesse's answer managed identity has to go trough a separate constructor which requires a namespace instead of an endpoint and an instance of ManagedIdentityCredential.

As I mentioned not all environments where we deploy have managed aged identities, some require a SharedAccessKey based connection string.

Instead introducing new "identity type" configuration parameters into our build process I've used a factory method to parse the connection string and call the correct constructor overload. Where its a managed identity It extracts the namespace from the endpoint setting.

        private static ServiceBusClient CreateServiceBusClient(string connectionString)
        {
            var cs = new DbConnectionStringBuilder();
            cs.ConnectionString = connectionString;
            if (cs.ContainsKey("Authentication") &&
                "Managed Identity".Equals(cs["Authentication"].ToString(), StringComparison.OrdinalIgnoreCase))
            {
                string endpoint = cs["Endpoint"].ToString() ?? String.Empty;
                if (endpoint.StartsWith(@"sb://", StringComparison.OrdinalIgnoreCase)) endpoint = endpoint.Substring(5);
                if (endpoint.EndsWith(@"/")) endpoint = endpoint.Substring(0, endpoint.Length - 1);
                return new ServiceBusClient(endpoint, new ManagedIdentityCredential());
            }

            return new ServiceBusClient(connectionString);
        }

it needs the Azure.Identity package and the namespace System.Data.Common for the connection string builder.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Twisted
  • 2,939
  • 4
  • 32
  • 54

2 Answers2

0

The clients in the Azure.Messaging.ServiceBus package support connection strings only in the format that the Azure portal returns them. The ;Authentication=Managed Identity token that you've included in your connection string is not a known token and is ignored, so the client does not have the information needed to perform authorization. A managed identity cannot be specified via connection string.

To use a managed identity, you'll use one of the constructor overloads that accepts a fully qualified namespace and a TokenCredential. An example can be found in the package Overview docs. Any of the Azure.Identity credentials can be used; you may want to take take a look at the managed identity section of the Azure.Identity overview.

Jesse Squire
  • 6,107
  • 1
  • 27
  • 30
  • For [Functions with Managed Identity](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/README.md): "__fullyQualifiedNamespace": ".servicebus.windows.net" – Sean Feldman Mar 18 '22 at 14:13
  • It's a shame that you are not able to support those connection strings anymore, it was an elegant way of managing identity in Microsoft.Azure.ServiceBus through a single configuration setting. Made the devops a breeze. – Twisted Mar 22 '22 at 10:04
  • @Twisted What is the current way of using Azure function with managed identity to connect with service bus both of local development using Visual Studio and when function is deployed ? – OpenStack Oct 01 '22 at 14:26
  • @SeanFeldman: What is the best way to connect to azure function with service bus using managed identity when running code locally or when azure function is deployed. following option is not working for me `__fullyQualifiedNamespace": ".servicebus.windows.net"` I created a new question: https://stackoverflow.com/questions/73915471/azure-function-how-to-use-defaultazurecredential-for-development-using-visual-st – OpenStack Oct 01 '22 at 14:35
  • Not sure about managed identiry within azure functions, didn't realize that was possible! In terms of upgrading my projects, I kept the connection string as it was and parsed it myself - if it has Authentication=Managed Identity I call the managed identity constructors otherwise pass through the connection string as before. It's not ideal but it means our DevOps process can still control the credentials. Hope this helps! – Twisted Oct 04 '22 at 19:55
0

I used this doc to use managed identity to connect to the Azure Service Bus.
Connection string or client secret are not required. The authorization is handled by DefaultAzureCredentials() which works well with system assigned managed identity.

Reference:

Tyler2P
  • 2,324
  • 26
  • 22
  • 31