0
votes

I am building a service that needs to create at runtime a servicebus namespace, topic and subscriptions. I need to genrate the sas token(or url) to the subscription created by the service and send it to other services in the system.

How can i generate the sas token with the azure python sdk

2

2 Answers

1
votes

If you want to generate SAS token for service bus with python, please refer to the document.

For example (I create a sas token for topic)

  1. Generate SAS token
sb_name='<service bus name>'
topic='<topic name>'
url=urllib.parse.quote_plus("https://{}.servicebus.windows.net/{}".format(sb_name,topic))
sas_value='your sas policy key value'
sas_name='your sas policy'
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. Test

    a. Send message

    
    
    POST https://<yournamespace>.servicebus.windows.net/<topic>/messages
    Authorization: SharedAccessSignature sr=https%3A%2F%2F<yournamespace>.servicebus.windows.net%2F<yourentity>&sig=<yoursignature from code above>&se=1438205742&skn=KeyName
    ContentType: application/atom+xml;type=entry;charset=utf-8
    
    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">This is a message.</string> 
    

    enter image description here

    b. Receive message

    DELETE https://{serviceNamespace}.servicebus.windows.net/{topicPath}/subscriptions/{subscriptionName}/messages/head   
    
    Authorization: SharedAccessSignature sr=https%3A%2F%2F<yournamespace>.servicebus.windows.net%2F<yourentity>&sig=<yoursignature from code above>&se=1438205742&skn=KeyName
    

    enter image description here

1
votes

I'd note in addition to Jim's accurate answer: one can also approach this using the azure-mgmt-servicebus SDK. It would require using azure.common.credentials.ServicePrincpalCredential for authentication, but would give a slightly more structured flow; not only to create the namespace and topic/subscription, but to create or update authorization rules against a given topic or the namespace itself, and then fetch your keys programmatically.

See the following as a self-contained example:

from azure.mgmt.servicebus import ServiceBusManagementClient
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.servicebus.models import AccessRights

client_id = 'REPLACEME'
client_secret = 'REPLACEME'
subscription = 'REPLACEME'
tenant = 'REPLACEME'
resource_group_name = 'REPLACEME'
namespace_name = 'REPLACEME'
authorization_rule_name = 'REPLACEME'
topic_name = 'REPLACEME'
subscription_name = 'REPLACEME'
authorization_rule_rights = [AccessRights.manage]

credential = ServicePrincipalCredentials(client_id, client_secret, tenant=tenant)

client = ServiceBusManagementClient(credential, subscription)

client.namespaces.create_or_update(resource_group_name, namespace_name)
client.topics.create_or_update(resource_group_name, namespace_name, topic_name)
client.subscriptions.create_or_update(resource_group_name, namespace_name, topic_name, subscription_name)
client.topics.create_or_update_authorization_rule(resource_group_name, namespace_name, topic_name, authorization_rule_name, authorization_rule_rights)
rule = client.topics.list_keys(resource_group_name, namespace_name, topic_name, authorization_rule_name)

As always, full disclosure, I'm one of the folks maintaining the python azure servicebus lib, so don't hesitate to shout if any of this is unclear.