Expose Service Bus Queue through API management
  • 24 Jun 2022
  • 2 Minutes to read
  • Contributors
  • Comments
  • Dark
    Light
  • PDF

Expose Service Bus Queue through API management

  • Comments
  • Dark
    Light
  • PDF

#ServerlessTips - Azure Service Bus
Author: Steef-Jan Wiggers Azure MVP

You can expose a service bus topic or queue endpoint through Azure API Management and thus allow access to these entities in a secure, and managed way. When creating an entity like a queue in a service bus namespace, you will have an HTTPS endpoint to it for example:
https://customevents.servicebus.windows.net/errors
You can arrange the access to this particular endpoint by adding a Shared Access Signature policy to it (means of access control).

Azure Service Bus Tip 02 - Picture 1.png

Next, you can harden the security to the endpoint by creating a proxy to it through Azure API Management, and thus delegating the authentication to the endpoint to API Management.

Moreover, the client can provide credentials to authentication against the proxy, i.e. API in API Management – which requires setting up authentication at APIM with, for instance, OAuth 2.0 (see Microsoft Docs - Protect an API by using OAuth 2.0 with Azure Active Directory and API Management).
Steps to add the endpoint as a proxy in API Management are:
• In API Management use the Blank API Template
• Add an operation

Azure Service Bus Tip 02 - Picture 2.png

• Change inbound policy, i.e. backend to https endpoint of the queue.
• Add a policy with the following content:

<policies>
    <inbound>
        <base />
        <cache-lookup-value key="errorsas" variable-name="cachedSasToken" />
        <choose>
            <when condition="@(context.Variables.GetValueOrDefault&lt;string>("cachedSasToken") == null)">
                <cache-store-value key="errorsas" value="@{
                        string resourceUri = "https://customevents.servicebus.windows.net/errors";
                        string keyName = "write_error";
                        string key = "BtV+FP1Y02uu0B/oYfDPLLe4JDPvA6rZ/tph10RRuVk=";
                        TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
                        var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 120);
                        string stringToSign = System.Uri.EscapeDataString(resourceUri) + "\n" + expiry;
                        HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
                        var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
                        var sasToken = String.Format("SharedAccessSignature sr={0}&amp;sig={1}&amp;se={2}&amp;skn={3}", 
                                        System.Uri.EscapeDataString(resourceUri),
                                        System.Uri.EscapeDataString(signature), expiry, keyName);
                        return sasToken;
                    }" duration="10" />
                <cache-lookup-value key="errorsas" variable-name="cachedSasToken" />
            </when>
        </choose>
        <set-header name="Authorization" exists-action="override">
            <value>@(context.Variables.GetValueOrDefault<string>("cachedSasToken"))</value>
        </set-header>
        <set-header name="Content-type" exists-action="override">
            <value>application/json</value>
        </set-header>
        <set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
        <set-header name="BrokerProperties" exists-action="override">
            <value>@{
               string reqData = context.Request.Body?.As<string>(true);
               dynamic data =  JsonConvert.DeserializeObject(reqData);
               string order =  data?.CustomerNumber;
               return string.Format("{{\"SessionId\":\"{0}\"}}", order);
            }</value>
        </set-header>
        <set-backend-service base-url="https://customevents.servicebus.windows.net/errors" />
    </inbound>
    <backend />
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Azure Service Bus Tip 02 - Picture 3.png
Next, you can test the API operation, and subsequently provide a client with API endpoint, and means of authentication to it (e.g. OAuth 2.0).
Furthermore, in case you want to isolate further the endpoint of the queue or topic choose Service Bus Premium tier. With the premium tier, you will get Virtual Network (VNet) support and thus prevent access to it through the public internet.

Also, get insights into Azure Service Bus messaging issues and improve monitoring.

Service Bus-1


Was this article helpful?