如何使用 Azure Function 中的 Azure Managed Identity 通过触发器访问服务总线?

How to use Azure Managed Identity in Azure Function to access Service Bus with a trigger?

我在 Azure 中创建了一个 ServiceBus 命名空间,以及一个主题和一个订阅。我还有一个简单的 Azure 版本 1 函数,它会触发 ServiceBus 中接收到的主题,如下所示:

[FunctionName("MyServiceBusTriggerFunction")]
public static void Run([ServiceBusTrigger("myTopic", "mySubscription", Connection = "MyConnection")]string mySbMsg, TraceWriter log)
{
    log.Info($"C# ServiceBus topic trigger function processed message: {mySbMsg}");
}

当我使用主题的共享访问策略在函数应用程序设置中定义连接字符串时,该函数很好地触发了 ServiceBus 中的主题,如下所示:

Endpoint=sb://MyNamespace.servicebus.windows.net/;SharedAccessKeyName=mypolicy;SharedAccessKey=UZ...E0=

现在,我想使用托管服务标识 (MSI) 而不是共享访问密钥来访问 ServiceBus。根据这个 (https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/services-support-msi) 应该是可以的,除非我误解了什么。不过我还没有成功。

我尝试的是

此设置中未触发该功能,所以我缺少什么或做错了什么? 如果有任何建议可以帮助我走得更远,我将不胜感激。谢谢

what am I missing or what am I doing wrong?

您可能会混淆 MSI 和共享访问 Policy.They 正在使用 不同的提供商来访问 Azure 服务总线 。您可以只使用连接字符串或只使用 MSI 进行身份验证。

当您使用 Managed Service Identity(MSI) 进行身份验证时,您需要使用以下代码为托管服务身份创建令牌提供程序。

TokenProvider.CreateManagedServiceIdentityTokenProvider(ServiceAudience.ServiceBusAudience).

TokenProvider 的实现使用 Microsoft.Azure.Services.AppAuthentication 库中的 AzureServiceTokenProviderAzureServiceTokenProvider 将根据环境采用一定数量的不同方法来获取访问令牌。然后初始化客户端来操作服务总线。 更详细的可以参考这个article.

当您使用 servicebus connectionstring 访问使用共享访问令牌 (SAS) 令牌提供程序时,您可以直接操作。

同意从 azure 函数我们不能直接访问像 ASB 这样的资源。但是,在这种情况下,仍然不需要直接在连接字符串中输入密码 "SharedAccessKeyName" 。 Azure 函数可以与 Azure KeyVault 一起使用。因此,可以将带有敏感信息的连接字符串作为秘密存储在 KeyVault 中,然后通过 KeyVault 授予系统分配的 Azure 函数访问身份,然后将门户中的设置值指定为 @Microsoft.KeyVault(SecretUri={theSecretUri}) 以下博客中提到了有关如何实现上述目标的详细信息。 https://medium.com/statuscode/getting-key-vault-secrets-in-azure-functions-37620fd20a0b

这仍将避免直接在 Azure 函数中指定连接字符串,并提供通过 Vault 的单点访问,以防出现安全漏洞

更新 Microsoft.Azure.WebJobs.Extensions.ServiceBus 版本 5.x

here.

中现在有最新版本包的官方文档
{
  "Values": {
    "<connection_name>__fullyQualifiedNamespace": "<service_bus_namespace>.servicebus.windows.net"
  }
}

上一个回答

这实际上现在看来是可行的,至少对我来说效果很好。您需要使用此连接字符串:

Endpoint=sb://service-bus-namespace-name.servicebus.windows.net/;Authentication=ManagedIdentity

我实际上没有在 Microsoft 站点上找到任何关于此的文档,但在博客中 here

Microsoft 确实有关于您可以使用的角色以及如何将它们限制在 here 范围内的文档。示例:

az role assignment create \
    --role $service_bus_role \
    --assignee $assignee_id \
    --scope /subscriptions/$subscription_id/resourceGroups/$resource_group/providers/Microsoft.ServiceBus/namespaces/$service_bus_namespace/topics/$service_bus_topic/subscriptions/$service_bus_subscription