rebus-org / Rebus.AzureQueues

:bus: Azure Storage Queues transport implementation for Rebus
https://mookid.dk/category/rebus
Other
7 stars 5 forks source link

Improved Azure Queues Authentication Options #21

Closed mirandaasm closed 11 months ago

mirandaasm commented 1 year ago

Hey man, hi there!

Is it possible to configure this provider to connect to the underlying Azure Queues service using the new authentication options available at the Azure.Storage.Queues package?

I was taking a look at the MS Docs, and was wondering if it could be possible to use MSI-Enabled authentication flow on Azure App Services and Functions running apps with this package deployed on.

All our Azure Apps have an "User-Assigned" Managed Identity configured on them, on which we assign the required roles to access all the data at the Storage service. With this setup ready, we can finally stop using connection strings and start using the apps' Service Principals to authenticate. We just didn't see this configuration option available on this package.

If there's no such feature available yet, we could try to PR you this as an enhancement. I believe it could be implemented pretty much the same way it was implemented at the https://github.com/rebus-org/Rebus.AzureTables repo.

Also, it could somewhat "close" the discussion you guys had at #20 πŸ˜ƒ

Microsoft Reference: https://github.com/Azure/azure-sdk-for-net/tree/Azure.Storage.Queues_12.13.0/sdk/storage/Azure.Storage.Queues#authenticate-the-client

mookid8000 commented 11 months ago

Hi @mirandaasm , I have no idea how I can have missed you posting this issue back in March! 😳

If you have found an elegant way to support using managed identities with Rebus.AzureQueues, I'd be happy to accept your PR πŸ™‚

mirandaasm commented 11 months ago

Hey man, hahahah, np! That's all right. πŸ˜ƒ

I kinda gave up on it. I mean, it already works if we properly implement a basic IQueueClientFactory type. So, no point on wasting time on it right now... It's a little bit different pattern from what you're using on Rebus.AzureTables but... Well, at least it works. πŸ˜„

Here's what I did, in case anyone else wants to do the same.


  1. Create a class that implements IQueueClientFactory:
public class AzureTokenCredentialQueueClientFactory : IQueueClientFactory
{
    private readonly Azure.Core.TokenCredential _tokenCredential;
    private readonly Uri _serviceEndpoint;

    public AzureTokenCredentialQueueClientFactory(Azure.Core.TokenCredential tokenCredential, Uri serviceEndpoint)
    {
        _tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential));
        _serviceEndpoint = serviceEndpoint ?? throw new ArgumentNullException(nameof(serviceEndpoint));
    }

    public async Task<QueueClient> GetQueue(string queueName)
    {
        return new QueueClient(
            new Uri(_serviceEndpoint, queueName ?? throw new ArgumentNullException(nameof(queueName))),
            _tokenCredential);
    }
}

  1. Use your preferred method to instantiate a new Azure.Core.TokenCredential object, eg:
 var tokenCredential = new Azure.Identity.DefaultAzureCredential(new Azure.Identity.DefaultAzureCredentialOptions { ManagedIdentityClientId = "Not really required, unless you're using User-Managed Identities" });

  1. Use your preferred method to instantiate a new IQueueClientFactory object, eg:
var serviceEndpoint = new Uri("https://my-awesome-storage-account.queue.core.windows.net");
var queueClientFactory = new AzureTokenCredentialQueueClientFactory(tokenCredential, serviceEndpoint);

  1. Configure Rebus Transport using the previously instantiated queueClientFactory, eg:
services.AddRebus(
    configure => configure
        .Transport(t => t.UseAzureStorageQueues(queueClientFactory, "your_queue"))
        .(...)
);

Maybe you could just put some of the above code inside the project? Like, the AzureTokenCredentialQueueClientFactory from step one could be provided within the package itself, to make it easier for people to use it.

Anyway, like I said, this package already provides a way to connect to the Storage Account using Azure Managed Identities, kinda... heh...

Feel free to close this issue too. No point on leave it open since I won't be able to provide much more than what I just pasted above, after all.

Thanks!

mookid8000 commented 11 months ago

Awesome, thanks! I've added your IQueueClientFactory implementation and the necessary configuration overloads to the package. It's out as Rebus.AzureQueues 4.0.0-alpha02 on NuGet.org now πŸ™‚