【问题标题】:Azure ServiceBus Invalid SignatureAzure ServiceBus 签名无效
【发布时间】:2026-02-16 18:45:01
【问题描述】:

我创建了一个使用 shared-access-signature npm 模块生成的 SAS TOKEN。当我尝试使用 Azure SDK 连接到服务总线时,出现以下错误。

com.microsoft.azure.servicebus.primitives.ServiceBusException: 
Error{condition=com.microsoft:auth-failed, description='InvalidSignature:
The token has an invalid signature.', info=null}

我的 SAS 令牌如下所示

SharedAccessSignature sr=https%3A%2F%2Fmy-servicebus-dev.servicebus.windows.net%2F&sig=somesig%2idonotdisclose0e1g%3D&se=1541700607.155&skn=RootManageSharedAccessKey

SAS TOKEN 应该如何使用?它应该是整个字符串还是只是除SharedAccessSignature 之外的部分?

请帮忙。我的线索不多了。

【问题讨论】:

  • 请分享您的代码以连接到 Azure 服务总线。如果您使用的是 SDK,我猜您不必生成 SAS。这应该由 SDK 自己完成。
  • 嗨,现在有更新吗?
  • 嗨,杰克,我的回答对你有帮助吗?
  • 嗨,Jay,对不起,我没有回复。我正在使用您的代码生成 SAS 令牌,但是当我尝试使用它连接到服务总线时,它给了我一个奇怪的错误。 com.microsoft.azure.servicebus.primitives.MessagingEntityNotFoundException我检查了门户网站,我在代码中使用的一切都很完美。

标签: java node.js azure azureservicebus azure-servicebus-topics


【解决方案1】:

SAS TOKEN 应该如何使用?它应该是整个字符串还是 只是 SharedAccessSignature 之外的部分?

根据我的测试,答案是肯定的。您需要将参数作为一个完整的字符串传递,包括SharedAccessSignature sr=

我使用您提供的 npm 库生成 sas 令牌。

var sas = require('shared-access-signature');

var url = 'https://******.servicebus.windows.net/BasicQueue';
var sharedAccessKeyName = 'RootManageSharedAccessKey';
var sharedAccessKey = '***';
var currentDate = new Date();
var expiry = currentDate.getTime() / 1000 + 3600; // We require expiry time in seconds since epoch.

var sas = require('shared-access-signature');
var signature = sas.generateServiceBusSignature(url, sharedAccessKeyName, sharedAccessKey, expiry);
console.log(signature);

然后在下面的Java代码中使用:

import com.microsoft.azure.servicebus.Message;
import com.microsoft.azure.servicebus.QueueClient;
import com.microsoft.azure.servicebus.ReceiveMode;
import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder;
import com.microsoft.azure.servicebus.primitives.ServiceBusException;
public class SendMessages {
    private static String entityPath = "BasicQueue";

    private static String namespaceName = "***";

    private static String sharedAccessSingature = "SharedAccessSignature sr=https%3A%2F%2F***.servicebus.windows.net%2FBasicQueue&sig=ewu7ZwgPgDVSHBZiYB7paBp94KuMtby%2BiwK0fDJ5GLM%3D&se=1541735153.139&skn=RootManageSharedAccessKey";


    public static void main(String[] args) throws ServiceBusException, InterruptedException {

        QueueClient sendClient = new QueueClient(new ConnectionStringBuilder(namespaceName, entityPath, sharedAccessSingature), ReceiveMode.PEEKLOCK);

        String test = "test for 111";

        Message message = new Message(test);

        sendClient.sendAsync(message).thenRunAsync(() -> {
            System.out.printf("\n\tMessage acknowledged: Id = %s", message.getMessageId());
        });

        System.out.println("send success");
    }
}

【讨论】:

  • 如果我使用主题,那么命名空间 url 应该指向一个主题或我试图从中读取消息的订阅?