Mark McGookin
Mark McGookin

Reputation: 1042

List Queues/Topics of Azure Service Bus using Rest API with SharedAccessKey

I am trying to list the Queues/Topics in an Azure Service Bus using the REST API.

When I try to connect I just get back a blank feed saying "This is the list of publicly-listed services currently available".

I am using the RootManageSharedAccessKey in the portal (for dev only, I can create a more restricted key later) so it should have all the access rights that I need, I just can't seem to get it to return anything. This documentation seems to suggest that this will work, but there's no actual working examples, just theoretical responses.

I have tried doing a GET request with the signature in the URL like this:

https://myservicebusnamespace.servicebus.windows.net/$Resources/Queues;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=MYSHAREDACCESSKEY

I have also tried doing it like this:

https://myservicebusnamespace.servicebus.windows.net/$Resources

and then setting the Authorization header to

WRAP access_token="MYSHAREDACCESSKEY="

Both times I just get this back

<feed xmlns="http://www.w3.org/2005/Atom">
    <title type="text">Publicly Listed Services</title>
    <subtitle type="text">This is the list of publicly-listed services currently available.</subtitle>
    <id>uuid:6a5d438d-1793-451b-be41-XXXXXXXXXXXX;id=XXXXXX</id>
    <updated>2020-06-28T13:03:04Z</updated>
    <generator>Service Bus 1.1</generator>
</feed>

If I change the url slightly to be:

https://myservicebusnamespace.servicebus.windows.net/$Resources/Queues/

I get a slightly different response back of:

<Error>
    <Code>401</Code>
    <Detail>claim is empty. TrackingId:c40a2bd2-490d-4b5b-adde-33bc89aa84ff_G36, SystemTracker:myservicebusnamespace.servicebus.windows.net:$Resources/Queues, Timestamp:2020-06-28T13:27:40</Detail>
</Error>

Which seems to suggest that I am not authorised, or I am missing something. If I add an acutual queue name to the end of that url, it goes back to the original response.

I believe there is another way to get this information by using subscription ids and pem keys... using the management urls (https://management.core.windows.net/{subscription ID}/services/ServiceBus/Namespaces/{Namespace}/Topics/) but this should all be possible using the format above, I just can't figure out the exact format required.

EDIT/UPDATE: If I don't include my auth claim, the result is exactly the same, suggesting that it's not seeing my auth claim or it's invalid. However if I include it, and just make it the token, without the WRAP bit at the start, I get an exception saying

<Error>
    <Code>401</Code>
    <Detail>MalformedToken: Invalid authorization header: The request is missing WRAP authorization credentials. TrackingId:7be2d7f0-c165-4658-8bf1-ea104c43defc_G28, SystemTracker:NoSystemTracker, Timestamp:2020-06-28T13:33:09</Detail>
</Error>

So it's like it's reading it then ignoring it?

Upvotes: 0

Views: 2265

Answers (1)

Jim Xu
Jim Xu

Reputation: 23141

If you want to list queues or topics we can use Azure service bus service rest api or Azure Resource Manager Rest API. For more details, please refer to the following steps

  • Azure service bus service rest api
  1. Generate SAS token. For more details, please refer to the document

    For example, I use python to create sas token

import hmac
import time
import hashlib
import base64
import urllib
sb_name='bowmantest'
// your entity path such as $Resources/topics (list topics) $Resources/queues(list queues)
topic='$Resources/topics' 
url=urllib.parse.quote_plus("https://{}.servicebus.windows.net/{}".format(sb_name,topic))
sas_value='' // your share access key 
sas_name='RootManageSharedAccessKey' // your share access rule name 
expiry = str(int(time.time() + 10000))
to_sign =(url + '\n' + expiry).encode('utf-8') 
sas = sas_value.encode('utf-8')
signed_hmac_sha256 = hmac.HMAC(sas, to_sign, hashlib.sha256)
signature = urllib.parse.quote(base64.b64encode(signed_hmac_sha256.digest()))
auth_format = 'SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}'
auth=auth_format.format(signature,expiry,sas_name,url)
print(auth)

  1. Call the rest API

1). list Queues

GET https://<namespace name>.servicebus.windows.net/$Resources/queues

Authorization <sas token>

enter image description here

2). List topics

GET https://<namespace name>.servicebus.windows.net/$Resources/topics

Authorization <sas token>

enter image description here

  • Azure Resource Manager Rest API
  1. create a service principal and assign Azure RABC role to the sp(I use Azure CLI)
az login
#it will create a service principal and assign contributor role to the sp
az ad sp create-for-rbac -n "jonsp2"

enter image description here

  1. Get Azure AD token
POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=<app id>
&scope=https://management.azure.com/.default
&client_secret=<app password>
&grant_type=client_credentials
  1. call the rest API

List Queues

GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ServiceBus/namespaces/{namespaceName}/queues?api-version=2017-04-01

Authorization Bearer <AD token>

enter image description here

Upvotes: 1

Related Questions