使用MSI的Azure功能访问服务总线

时间:2018-08-20 14:29:01

标签: azure-functions azureservicebus

我已经在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),除非我有误解,否则应该有可能。我还没有设法使它工作。

我尝试的是

  • 为我在Azure门户中的功能设置“托管服务身份”为“开”
  • 为Azure门户的ServiceBus访问控制部分中的功能赋予所有者角色
  • 像这样设置MyFunction的连接字符串: Endpoint = sb://MyNamespace.servicebus.windows.net/

该功能未在此设置中触发,因此我缺少什么或做错了什么? 如果有任何建议可以帮助我进一步发展,我将不胜感激。谢谢。

3 个答案:

答案 0 :(得分:2)

  

我想念什么或我做错了什么?

您可能会混合使用MSI和共享访问策略。它们使用不同的提供程序来访问Azure Servicebus 。您可以只使用连接字符串,也可以只使用MSI进行身份验证。

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

TokenProvider.CreateManagedServiceIdentityTokenProvider(ServiceAudience.ServiceBusAudience)

TokenProvider的实现使用在AzureServiceTokenProvider库中找到的Microsoft.Azure.Services.AppAuthenticationAzureServiceTokenProvider将根据环境采用一定数量的不同方法来获取访问令牌。然后初始化客户端以运行服务总线。 有关更多详细信息,请参阅此article

当您使用servicebus连接字符串通过共享访问令牌(SAS)令牌提供程序访问哪个字符串时,可以直接进行操作。

答案 1 :(得分:2)

更新 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

答案 2 :(得分:0)

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

这仍将避免直接在Azure函数中指定连接字符串,并在出现安全漏洞的情况下禁用通过Vault的单点访问