【问题标题】:Read Azure ServiceBus Namespace connection string during deployment [duplicate]在部署期间读取 Azure ServiceBus 命名空间连接字符串 [重复]
【发布时间】:2021-09-25 01:58:33
【问题描述】:

我正在尝试从 Azure 函数 (C#) 向 Azure ServiceBus 队列发送消息。为此,我需要 Service Bus 命名空间的 ConnectionString(或者可能传递 Azure.Core.TokenCredential)。

将 ConnectionString 传递给 ServiceBusClient 构造函数时,我确实可以工作。

string connectionString = "Endpoint=sb://<servicebus-name>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<access-key>";
var client = new ServiceBusClient(connectionString);
var sender = client.CreateSender(queueName);
...
sender.SendMessagesAsync()

问题是部署应该是自动化的,Function 和 ServiceBus 是使用资源模板部署的。因此,SharedAccessKey 是在部署时创建的。如果我可以读取资源模板中的 AccessKey,我可以设置一个应用程序设置,然后函数可以读取该设置。但是,我找不到在资源模板中获取 AccessKey 的方法。有可能吗?

我尝试过的另一件事是使用TokenCredential 创建ServiceBusClient,如下所示:

var credentials = new DefaultAzureCredential();
string[] ss = queueUrl.Split('/', StringSplitOptions.RemoveEmptyEntries);
var fullyQualifiedName = ss[^2];
var queueName = ss[^1];

var client = new ServiceBusClient(fullyQualifiedName, credentials);
var sender = client.CreateSender(queueName);
using ServiceBusMessageBatch messageBatch = sender.CreateMessageBatchAsync().Result; 

当我这样做时,我得到:

Unauthorized access. 'Send' claim(s) are required to perform this operation. Resource: 'sb://<servicebus-name>.servicebus.windows.net/<queuename>'. 

我不完全理解 DefaultAzureCredential 应该如何工作。是否有可能以某种方式解决这个权限问题(这是在 Azure 函数中)?

我的解决方法

我有一个解决方法,在部署资源模板后需要一个额外的步骤。使用 Azure CLI 读取 ServiceBus 命名空间 ConnectionString,然后使用该值更新应用程序设置。然后该函数正在从应用程序设置中读取连接字符串。

$ cs=$(az servicebus namespace authorization-rule keys list --namespace-name <Namespace> -n RootManageSharedAccessKey -g <resource-group> -o json | jq -r '.primaryConnectionString')
$ az functionapp config appsettings set --settings ServiceBusNamespaceConnectionStringCLI=$cs -g <resource-group> -n <function-name>
...
- name: ServiceBusNamespaceConnectionStringCLI
  slotSetting: false
  value: Endpoint=sb://<servicebus-name>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<access-key>

如果可能,我不希望使用这个额外的步骤,而是在模板或代码中完成所有操作。有什么想法吗?

【问题讨论】:

标签: azure azure-functions azureservicebus azure-resource-manager


【解决方案1】:

感谢Get the Service Bus SharedAccessKey Programatically Using Bicep这个答案,我发现了如何在资源模板中获取connectionString。这就是我使用应用程序设置将连接字符串传递给函数的方式。

"appSettings": [
  {
    "name": "ServiceBusConnectionString",
    "value": "[listKeys(resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', variables('serviceBusName'), '    RootManageSharedAccessKey'), '2021-06-01-preview').primaryConnectionString]"
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-05
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    相关资源
    最近更新 更多