HTTP-сообщение Powershell для очереди служебной шины возвращает 401 - PullRequest
0 голосов
/ 30 апреля 2020

Попытка отправить сообщение в очередь служебной шины, которую я настроил, и продолжить получать несанкционированный возврат 401.

Я попытался настроить токен SAS сам, используя этот метод

$ResourceGroupName = 'myResourceGroup'
$NameSpaceName = "serviceBusNameSpace"
$QueueName = "myQueueName"
$PolicyName = "RootManageSharedAccessKey"
$body = "test message"

$Namespace = (Get-AzServiceBusNamespace -ResourceGroupName $ResourceGroupName -Name $namespacename).Name
$key = (Get-AzServiceBusKey -ResourceGroupName $ResourceGroupName -Namespace $namespacename -Name $PolicyName).PrimaryKey

$origin = [DateTime]"1/1/1970 00:00" 
$Expiry = (Get-Date).AddMinutes(5)    

#compute the token expiration time.
$diff = New-TimeSpan -Start $origin -End $Expiry 
$tokenExpirationTime = [Convert]::ToInt32($diff.TotalSeconds)

#Create a new instance of the HMACSHA256 class and set the key to UTF8 for the size of $Key
$hmacsha = New-Object -TypeName System.Security.Cryptography.HMACSHA256
$hmacsha.Key = [Text.Encoding]::UTF8.GetBytes($Key)

$scope = "https://$Namespace.servicebus.windows.net/"
#create the string that will be used when cumputing the hash
$stringToSign = [Web.HttpUtility]::UrlEncode($scope) + "`n" + $tokenExpirationTime

#Compute hash from the HMACSHA256 instance we created above using the size of the UTF8 string above.
$hash = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
#Convert the hash to base 64 string
$signature = [Convert]::ToBase64String($hash)
$fullResourceURI = "https://$Namespace.servicebus.windows.net/$QueueName"
#create the token
$token = [string]::Format([Globalization.CultureInfo]::InvariantCulture, `
         "SharedAccessSignature sr={0}sig={1}&se={2}&skn={3}", `
         [Web.HttpUtility]::UrlEncode($fullResourceURI), `
         [Web.HttpUtility]::UrlEncode($signature), `
         $tokenExpirationTime, $PolicyName) 

$headers = @{ "Authorization" = "$token"; "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" }
$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$headers.Add("BrokerProperties", "{}")

#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing

Я также пытался сгенерировать его с помощью встроенного командлета в Az.ServiceBus

$ResourceGroupName = 'myResourceGroup'
$NameSpaceName = "serviceBusNameSpace"
$QueueName = "myQueueName"
$PolicyName = "RootManageSharedAccessKey"

$body = "test message"
$expiry = (Get-Date).AddHours(2)
$authRule = Get-AzServiceBusAuthorizationRule -ResourceGroupName $ResourceGroupName -Namespace $NamespaceName
$token = New-AzServiceBusAuthorizationRuleSASToken -AuthorizationRuleId $authRule.Id -KeyType Primary -ExpiryTime $Expiry

$headers = @{ "Authorization" = "SharedAccessSignature $($token.SharedAccessSignature)"; "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" }
$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$headers.Add("BrokerProperties", "{}")

#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing

И то, и другое выдаёт мне 401 несанкционированную ошибку

Invoke-WebRequest : The remote server returned an error: (401) Unauthorized.
At line:9 char:17
+ ... $response = Invoke-WebRequest -Uri $uri -Headers $headers -Method Pos ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Я не уверен, что еще сделать. Есть ли параметр, который мне нужно настроить для моей очереди на портале azure?

Нашли решение. UT C время истечения токена до его отправки, в дополнение к некорректной подписи SAS

Окончательное редактирование кода ниже

$key = (Get-AzServiceBusKey -ResourceGroupName $ResourceGroupName -Namespace $namespacename -Name $PolicyName).PrimaryKey

$origin = [DateTime]"1/1/1970 00:00" 
$Expiry = (Get-Date).AddMinutes(20)
$Expiry = $Expiry.ToUniversalTime()    

#compute the token expiration time.
$diff = New-TimeSpan -Start $origin -End $Expiry 
$tokenExpirationTime = [Convert]::ToInt32($diff.TotalSeconds)


$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$scope = "https://$Namespace.servicebus.windows.net/$QueueName"
#create the string that will be used when cumputing the hash
$stringToSign = [Web.HttpUtility]::UrlEncode($scope) + "`n" + $tokenExpirationTime

#Create a new instance of the HMACSHA256 class and set the key to UTF8 for the size of $Key
$hmacsha = New-Object -TypeName System.Security.Cryptography.HMACSHA256
$hmacsha.Key = [Text.Encoding]::UTF8.GetBytes($Key)


#Compute hash from the HMACSHA256 instance we created above using the size of the UTF8 string above.
$hash = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
#Convert the hash to base 64 string
$signature = [Convert]::ToBase64String($hash)

#create the token
$token = [string]::Format([Globalization.CultureInfo]::InvariantCulture, `
        "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", `
        [Web.HttpUtility]::UrlEncode($scope), `
        [Web.HttpUtility]::UrlEncode($signature), `
        $tokenExpirationTime, $PolicyName) 

$headers = @{ "Authorization" = "$token"}
$headers.Add("Content-Type", "application/atom+xml;type=entry;charset=utf-8")

#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Я внес в ваш скрипт некоторые изменения, и он работает нормально.

$ResourceGroupName = 'myResourceGroup'
$Namespace = "serviceBusNameSpace"
$QueueName = "myQueueName"
$PolicyName = "RootManageSharedAccessKey"
$body = "test message"

$key = (Get-AzServiceBusKey -ResourceGroupName $ResourceGroupName -Namespace $Namespace -Name $PolicyName).PrimaryKey

$origin = [DateTime]"1/1/1970 00:00" 
$Expiry = (Get-Date).AddMinutes(5)    

#compute the token expiration time.
$diff = New-TimeSpan -Start $origin -End $Expiry 
$tokenExpirationTime = [Convert]::ToInt32($diff.TotalSeconds)

#Create a new instance of the HMACSHA256 class and set the key to UTF8 for the size of $Key
$hmacsha = New-Object -TypeName System.Security.Cryptography.HMACSHA256
$hmacsha.Key = [Text.Encoding]::UTF8.GetBytes($Key)

#create the string that will be used when cumputing the hash
$stringToSign = [Web.HttpUtility]::UrlEncode($Namespace) + "`n" + $tokenExpirationTime

#Compute hash from the HMACSHA256 instance we created above using the size of the UTF8 string above.
$hash = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
#Convert the hash to base 64 string
$signature = [Convert]::ToBase64String($hash)

#create the token
$token = [string]::Format([Globalization.CultureInfo]::InvariantCulture, `
        "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", `
        [Web.HttpUtility]::UrlEncode($Namespace), `
        [Web.HttpUtility]::UrlEncode($signature), `
        $tokenExpirationTime, $PolicyName) 

$headers = @{ "Authorization" = "$token"; "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" }
$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$headers.Add("BrokerProperties", "{}")

#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing

Я сделал следующие изменения:

  1. Вы не делаете необходимо создать переменную области видимости. Вам нужно передать $ Namespace в stringToSign.

  2. Вам не нужно использовать Get-AzServiceBusNamespace , чтобы получить имя пространства имен в качестве вашего уже принимают это как ввод данных пользователем.

0 голосов
/ 04 мая 2020

См. Пост-редактирование.

Время истечения токена не было преобразовано в UT C, поэтому оно всегда истекло, в дополнение к неправильной конфигурации строки конфигурации токена SaS.

...