我有一个
.Net8
dotnet-isolated
Azure Durable Functions 项目。
我正在使用 ServiceBusTrigger
从服务总线队列获取消息:
[Function(nameof(Function1))]
public async Task Run(
[ServiceBusTrigger("some-queue-name", Connection = "ServiceBus")]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
// Complete the message
await messageActions.CompleteMessageAsync(message);
}
在
local.settings.json
文件中有服务总线连接的设置:
"ServiceBus:fullyQualifiedNamespace": "****.servicebus.windows.net",
"ServiceBus:tenantId": "***************",
"ServiceBus:clientId": "***************",
"ServiceBus:clientSecret": "***************"
这样ServiceBus触发函数就可以连接Service Bus并接收来自Service Bus的消息了。
但是,我想连接到服务总线而不指定客户端密钥,仅使用令牌凭据或任何其他工作方式。
当我在 Program.cs 中指定时
services.AddAzureClients(builder =>
{
var managedIdentityCredential = new ManagedIdentityCredential(azureClientId);
builder
.AddServiceBusClient("******.servicebus.windows.net")
.WithCredential(managedIdentityCredential);
});
我无法连接到服务总线,有例外:
[2024-02-16T14:12:42.315Z] System.Private.CoreLib:未经授权的访问。执行此操作需要“监听”声明。资源:'sb://****.servicebus.windows.net/{queue-name}'。 TrackingId:,SystemTracker:*****,时间戳:2024-02-16T14:13:01
当我更改 local.settings.json 中的设置时,如 Microsoft 指南所说,
"ServiceBus:credential": "managedidentity",
"ServiceBus:clientId": "*******",
应用程序启动时没有任何错误,但无法从服务总线队列接收任何消息。 如果我使用同样的故事
managedIdentityResourceId
"ServiceBus:credential": "managedidentity",
"ServiceBus:managedIdentityResourceId": "/subscriptions/************/resourceGroups/Default-ServiceBus-WestEurope/providers/Microsoft.ServiceBus/namespaces/********"
仍然没有错误,但没有收到消息。
但是使用本地设置中指定的客户端密钥,它就可以工作。 客户端具有发送/接收服务总线消息所需的所有角色。
那么如何使用ServiceBusTrigger和ManagedIdentity从服务总线队列接收消息呢?
AFAIK 并根据 SO-Thread,在本地计算机中管理身份使用是不可能的。但您可以使用托管身份,并可以按照以下流程在门户中执行相同的操作:
在本地创建函数应用程序和服务总线队列触发器:
Function.cs:
using System;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace FunctionApp124
{
public class Function1
{
private readonly ILogger<Function1> _logger;
public Function1(ILogger<Function1> logger)
{
_logger = logger;
}
[Function(nameof(Function1))]
public async Task Run(
[ServiceBusTrigger("myqueue", Connection = "rithcon")]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
// Complete the message
await messageActions.CompleteMessageAsync(message);
}
}
}
local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"rithcon__fullyQualifiedNamespace":"rith75.servicebus.windows.net"
}
}
Program.cs:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
在 Portal 中创建一个 Function 应用程序,然后
On Managed Identity
在 azure 函数中:
现在
deploy the function to portal
。
然后将角色
Azure Service Bus Data Receiver
授予服务总线中的托管身份:
在环境变量部分添加:
Output:
然后它的工作原理如下: