Azure Service Bus发送消息报错:无效的授权令牌签名
Azure Service Bus队列发送消息401授权错误排查与解决
问题场景
使用以下PowerShell代码向Azure Service Bus队列发送消息时,调用Invoke-WebRequest触发401授权错误:
param ( [Parameter(Mandatory = $true)][string] $ResourceGroupName, [Parameter(Mandatory = $true)][string] $NamespaceName, [Parameter(Mandatory = $true)][string] $QueueName, [Parameter(Mandatory = $false)][string] $PolicyName = 'SASPolicy' ) $test_msg = [PSCustomObject] @{ "test" = "This is a test message" } | ConvertTo-Json -Compress $authorizationId = (Get-AzServiceBusAuthorizationRule -ResourceGroupName $ResourceGroupName -NamespaceName $NamespaceName -QueueName $QueueName).Id $token = (New-AzServiceBusAuthorizationRuleSASToken -AuthorizationRuleId $authorizationId -KeyType PrimaryKey -ExpiryTime Get-Date.AddHours(1.0)).SharedAccessSignature $auth_headers = @{ "Authorization" = "SharedAccessSignature $token"; "Content-Type" = "application/json" } $uri = "https://$NamespaceName.servicebus.windows.net/$QueueName/messages" $http_statuscode = Invoke-WebRequest -Uri $uri -Headers $auth_headers -Method Post -Body $test_msg Write-Host "Message sent successfully: $http_statuscode.StatusCode"
错误信息:
响应状态码未表示成功:401 (SubCode=40103: Invalid authorization token signature)。
问题原因与修复
1. ExpiryTime参数格式错误
代码中-ExpiryTime Get-Date.AddHours(1.0)未正确执行日期计算,传递的是字符串而非DateTime对象,导致令牌过期时间无效,签名验证失败。
修复:将其改为(Get-Date).AddHours(1.0),确保生成有效的过期时间。
2. 未指定目标SAS Policy获取AuthorizationRule
Get-AzServiceBusAuthorizationRule未添加-Name $PolicyName参数,默认会返回该队列的所有授权规则,此时取.Id可能拿到的不是目标Policy的ID,导致用错误的密钥生成令牌。
修复:添加-Name $PolicyName参数,精准获取目标授权规则的ID。
3. Authorization头格式冗余
New-AzServiceBusAuthorizationRuleSASToken返回的SharedAccessSignature已经包含完整的SAS令牌前缀(格式为SharedAccessSignature sr=...),代码中额外添加SharedAccessSignature 前缀会导致令牌格式错误。
修复:直接将$token赋值给Authorization头的值,无需额外前缀。
修正后的完整代码
param ( [Parameter(Mandatory = $true)][string] $ResourceGroupName, [Parameter(Mandatory = $true)][string] $NamespaceName, [Parameter(Mandatory = $true)][string] $QueueName, [Parameter(Mandatory = $false)][string] $PolicyName = 'SASPolicy' ) $test_msg = [PSCustomObject] @{ "test" = "This is a test message" } | ConvertTo-Json -Compress # 精准获取目标Policy的AuthorizationRule ID $authorizationRule = Get-AzServiceBusAuthorizationRule -ResourceGroupName $ResourceGroupName -NamespaceName $NamespaceName -QueueName $QueueName -Name $PolicyName $authorizationId = $authorizationRule.Id # 生成SAS令牌,使用正确的过期时间格式 $sasTokenResult = New-AzServiceBusAuthorizationRuleSASToken -AuthorizationRuleId $authorizationId -KeyType PrimaryKey -ExpiryTime (Get-Date).AddHours(1.0) $token = $sasTokenResult.SharedAccessSignature # Authorization头直接使用生成的令牌,无需额外前缀 $auth_headers = @{ "Authorization" = $token; "Content-Type" = "application/json" } $uri = "https://$NamespaceName.servicebus.windows.net/$QueueName/messages" try { $http_response = Invoke-WebRequest -Uri $uri -Headers $auth_headers -Method Post -Body $test_msg Write-Host "Message sent successfully: $($http_response.StatusCode)" } catch { Write-Host "Failed to send message: $_" }
内容的提问来源于stack exchange,提问作者nobody
相关产品推荐
相关产品推荐

