Azure Spring应用向Service Bus发消息遇权限错误及令牌刷新疑问
问题描述
尝试从Azure Spring应用向Azure Service Bus Queue发送消息,Spring应用已配置系统分配的托管标识,并被赋予Azure Service Bus Data Sender RBAC角色,但仍收到权限错误:
logger: com.azure.core.amqp.implementation.RetryUtil message: ReactorSender connectionId[MF_1b9f17_166...] linkName[testapptestapp]: Waiting for send and receive handler to be ACTIVE Unauthorized access. 'Send' claim(s) are required to perform this operation. Resource: 'sb://servicebus-namespace.servicebus.windows.net/testapp'. TrackingId:8479..., SystemTracker:gateway5, Timestamp:2022-08-10T09:46:42, errorContext[NAMESPACE: servicebus-namespace.servicebus.windows.net. ERROR CONTEXT: N/A, PATH: testapp, REFERENCE_ID: testapptestapp, LINK_CREDIT: 0]
另外发现linkName显示为testapptestapp(重复了队列名),预期应为testapp。
使用的Java代码:
TokenCredential credential = new DefaultAzureCredentialBuilder() .build(); // 该凭据由Azure AD托管(角色:Azure Service Bus Data Sender) ServiceBusSenderClient senderClient = new ServiceBusClientBuilder() .credential("servicebus-namespace.servicebus.windows.net", credential) .sender() .queueName("testapp") .buildClient(); senderClient.sendMessage(new ServiceBusMessage("test-message"));
错误日志前的相关日志:
logger: com.azure.core.amqp.implementation.ActiveClientTokenManager message: { [-] az.sdk.message: Scheduling refresh token task. scopes: https://servicebus.azure.net/.default logger: com.azure.identity.ManagedIdentityCredential message: Azure Identity => Managed Identity environment: AZURE VM IMDS ENDPOINT logger: com.azure.identity.ManagedIdentityCredential message: Azure Identity => getToken() result for scopes [https://servicebus.azure.net/.default]: SUCCESS logger: com.azure.identity.ChainedTokenCredential message: Azure Identity => Attempted credential ManagedIdentityCredential returns a token logger: com.azure.identity.ChainedTokenCredential message: Azure Identity => Attempted credential EnvironmentCredential is unavailable.
疑问:错误前的令牌刷新任务是什么原因?是否因未收到刷新令牌导致发送失败?
问题分析与解决
1. 令牌刷新任务的说明
日志中的"Scheduling refresh token task"是Azure SDK的正常机制:
- Azure AD令牌默认有效期为1小时,SDK会自动在令牌过期前调度刷新任务,提前获取新令牌,避免因令牌过期中断业务。
- 从后续日志可见,
ManagedIdentityCredential已成功获取到令牌,因此发送失败与未收到刷新令牌无关。
2. "缺少Send声明"的排查方向
(1) RBAC角色分配有效性检查
- 确认Azure Service Bus Data Sender角色是直接分配给目标Spring应用的系统托管标识,且分配范围覆盖目标Service Bus命名空间或具体队列
testapp。 - RBAC角色分配存在最长15分钟的生效延迟,若刚完成角色分配,等待一段时间后再测试。
(2) 令牌范围与受众验证
- 代码中默认使用的
https://servicebus.azure.net/.default范围符合要求,也可显式指定该范围以消除潜在的SDK默认行为问题:TokenCredential credential = new DefaultAzureCredentialBuilder().build(); ServiceBusSenderClient senderClient = new ServiceBusClientBuilder() .credential("servicebus-namespace.servicebus.windows.net", credential, "https://servicebus.azure.net/.default") .sender() .queueName("testapp") .buildClient(); - 解析获取到的令牌,检查是否包含
Send权限声明,以及令牌的受众是否为https://servicebus.azure.net。
(3) 托管标识身份验证验证
- 确认Azure Spring应用的系统分配托管标识已启用,且在Azure门户中能正常查看该标识的详情。
- 使用Azure CLI验证托管标识的令牌获取能力:
若能成功获取令牌,说明身份验证环节无问题,需进一步排查RBAC权限。az login --identity az account get-access-token --resource https://servicebus.azure.net
3. linkName重复的问题说明
linkNametestapptestapp是SDK内部生成的链接标识,由队列名与客户端默认标识拼接而成,属于SDK的正常行为,不会影响消息发送功能,无需额外处理。
内容的提问来源于stack exchange,提问作者Boommeister
相关产品推荐
相关产品推荐

