使用python SAS令牌连接到服务总线

时间:2017-11-21 20:59:46

标签: azure azureservicebus

我需要使用SAS令牌连接到azure服务总线(生成并连接)。

我没有看到python实现的任何内容。

此链接提供了Eventhubs的实现 -

https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token#python

不确定我在哪里可以找到servicebus的python实现。

2 个答案:

答案 0 :(得分:1)

我找到了一种可以对ServiceBusService类进行操作的方法。 运行“ pip install azure.servicebus”后,我将其导入为:

from azure.servicebus.control_client import ServiceBusService

ServiceBusService构造函数采用一个称为“身份验证”的参数,默认情况下未指定。

如果您进入ServiceBusService init 文件,则可以看到如何更详细地处理身份验证。

if authentication:
        self.authentication = authentication
    else:
        if not account_key:
            account_key = os.environ.get(AZURE_SERVICEBUS_ACCESS_KEY)
        if not issuer:
            issuer = os.environ.get(AZURE_SERVICEBUS_ISSUER)

        if shared_access_key_name and shared_access_key_value:
            self.authentication = ServiceBusSASAuthentication(
                shared_access_key_name,
                shared_access_key_value)
        elif account_key and issuer:
            self.authentication = ServiceBusWrapTokenAuthentication(
                account_key,
                issuer)

如果未传递自定义身份验证对象,则它将尝试使用ServiceBusSASAuthentication类,如果您填充shared_access_key_name和shared_access_key_value,则该类为默认设置。

因此,如果您跳到ServiceBusSASAuthentication类,则会注意到一些有用的信息。

class ServiceBusSASAuthentication:
    def __init__(self, key_name, key_value):
        self.key_name = key_name
        self.key_value = key_value
        self.account_key = None
        self.issuer = None

    def sign_request(self, request, httpclient):
        request.headers.append(
            ('Authorization', self._get_authorization(request, httpclient)))

    def _get_authorization(self, request, httpclient):
        uri = httpclient.get_uri(request)
        uri = url_quote(uri, '').lower()
        expiry = str(self._get_expiry())

        to_sign = uri + '\n' + expiry
        signature = url_quote(_sign_string(self.key_value, to_sign, False), '')

        auth_format = 'SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}'  # <----awww, yeah
        auth = auth_format.format(signature, expiry, self.key_name, uri)

        return auth  # <--after inserting values into string, the SAS Token is just returned.

    def _get_expiry(self):  # pylint: disable=no-self-use
        '''Returns the UTC datetime, in seconds since Epoch, when this signed
        request expires (5 minutes from now).'''
        return int(round(time.time() + 300))

sign_request函数是唯一在进行身份验证时由ServiceBusService类直接引用的函数,但是您会注意到,它所做的全部就是向请求中添加身份验证标头... SAS令牌。

因此,在这一点上,我掌握了制作自己的身份验证类所需的所有信息。我做了一个看起来像这样的东西。

class ServiceBusSASTokenAuthentication:
    def __init__(self, sas_token):
        self.sas_token = sas_token

    # this method is the one used by ServiceBusService for authentication, need to leave signature as is
    # even though we don't use httpClient like the original.
    def sign_request(self, request, httpclient):
        request.headers.append(
            ('Authorization', self._get_authorization())
        )

    def _get_authorization(self):
        return self.sas_token

我可能可以一起摆脱_get_auth函数,但是我还没有完善一切。

因此,现在,如果您使用有效的SAS令牌在ServiceBusService构造函数中像这样调用此类,它应该可以工作。

            subscription_client = ServiceBusService(
                authentication=ServiceBusSASTokenAuthentication(sas_token=sas_token),
                service_namespace=service_namespace
            )

答案 1 :(得分:0)

使用Azure Portal创建服务总线后,ServiceBusService对象使您可以使用队列。

关于创建队列,将消息发送到队列,使用python从队列接收消息以编程方式访问服务总线的更多信息,请按照此document进行操作。