You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加Azure Function读取队列后,Service Bus写入代码报401错误求助

问题分析与解决方案

401 InvalidSignature异常排查

出现该异常的核心原因是写入代码使用的身份凭证签名无效,结合你的场景,优先排查以下几点:

  • 确认写入身份(本地开发为当前登录Azure的用户,Azure部署为托管身份)已被分配Service Bus Data Sender角色(需在Service Bus命名空间层级或队列层级配置)
  • 本地开发环境中,若存在多个Azure身份(如Azure CLI、Visual Studio、Azure PowerShell),可能导致DefaultAzureCredential获取到错误的身份,需显式指定身份来源
  • 清除本地Token缓存:删除%USERPROFILE%\.azure\accessTokens.json文件后重新运行写入代码

修改后的消息写入代码(修复401问题)

以下是调整后的无密码写入代码,增加了身份指定和Token配置,避免签名异常:

using Azure.Messaging.ServiceBus;
using Azure.Identity;

// 配置Service Bus命名空间和队列名称
string fullyQualifiedNamespace = "<你的Service Bus命名空间>.servicebus.windows.net";
string queueName = "<你的队列名称>";

// 显式指定使用Visual Studio身份(可根据实际环境替换为AzureCliCredential、ManagedIdentityCredential等)
var credential = new VisualStudioCredential();

// 创建ServiceBusClient,配置Token刷新选项
var clientOptions = new ServiceBusClientOptions
{
    TokenCredentialOptions = new TokenCredentialOptions
    {
        AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
    }
};

await using var client = new ServiceBusClient(fullyQualifiedNamespace, credential, clientOptions);
ServiceBusSender sender = client.CreateSender(queueName);

// 构造并发送消息
string messageBody = "测试消息";
var message = new ServiceBusMessage(messageBody);

await sender.SendMessageAsync(message);
Console.WriteLine($"消息已发送: {messageBody}");

Azure Function读取成功后发送消息的实现

使用Service Bus触发的Function,读取消息处理完成后,再向指定队列发送确认消息:

1. 安装NuGet包

确保Function项目安装以下包:

Azure.Messaging.ServiceBus
Microsoft.Azure.Functions.Extensions
Microsoft.Azure.WebJobs.Extensions.ServiceBus
Azure.Identity

2. Function代码实现

using Azure.Messaging.ServiceBus;
using Azure.Identity;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace ServiceBusFunctionDemo
{
    public class ServiceBusReadAndSendFunction
    {
        private readonly ServiceBusClient _serviceBusClient;
        private readonly string _targetQueueName = "<发送确认消息的队列名称>"; // 可复用原队列或新队列

        public ServiceBusReadAndSendFunction()
        {
            // 使用托管身份(Azure部署)或本地身份(开发环境)创建ServiceBusClient
            string fullyQualifiedNamespace = "<你的Service Bus命名空间>.servicebus.windows.net";
            var credential = new DefaultAzureCredential();
            _serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);
        }

        [FunctionName("ServiceBusReadAndSend")]
        public async Task Run(
            [ServiceBusTrigger("<原读取队列名称>", Connection = "ServiceBusConnection")] ServiceBusReceivedMessage message,
            ServiceBusMessageActions messageActions,
            ILogger log)
        {
            log.LogInformation($"收到消息: {message.Body}");

            try
            {
                // 处理消息逻辑(此处省略业务代码)

                // 处理成功后发送确认消息
                var sender = _serviceBusClient.CreateSender(_targetQueueName);
                var confirmMessage = new ServiceBusMessage($"消息 {message.MessageId} 已成功处理");
                await sender.SendMessageAsync(confirmMessage);
                log.LogInformation($"已发送确认消息");

                // 完成消息,从队列移除
                await messageActions.CompleteMessageAsync(message);
            }
            catch (Exception ex)
            {
                log.LogError(ex, "处理消息失败");
                // 异常时放弃消息,重新入队
                await messageActions.AbandonMessageAsync(message);
            }
        }
    }
}

3. 配置文件(local.settings.json)

本地开发时,配置无密码连接(无需连接字符串):

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "ServiceBusConnection": "<你的Service Bus命名空间>.servicebus.windows.net"
  }
}

关键注意事项

  • Azure部署Function时,需为Function的托管身份分配Service Bus Data Receiver(读取原队列)和Service Bus Data Sender(发送确认消息)角色
  • 本地开发时,确保当前登录Azure的用户拥有上述对应角色

内容的提问来源于stack exchange,提问作者Siegfried

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:22:31