Expose Service Bus Queue through API management
    • Dark
      Light
    • PDF

    Expose Service Bus Queue through API management

    • Dark
      Light
    • PDF

    Article summary

    #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?