Exposing Azure Service Bus through APIM, generating a SAS Token

 

On one of my recent projects, a client application was required to place a message onto an Azure Service Bus by using a HTTP endpoint rather than using the Service Bus SDK and with the following constraints.

·       The client is unable to generate the Service Bus SAS token.

·       Service Bus Session Id needs to be set to the customer number found in the message to ensure ordered delivery by the consumer.

·       Custom HTTP Request Headers may be used.

I decided upon a solution that uses Azure APIM to expose the Service Bus endpoint.

1.     The first step of this solution  is to create an Azure Service Bus with a queue called ‘apimqueue.

Please refer below screen shot.





2.    Next click on created queue and navigate Shared access policy and added ‘apimqueuesend’ which has only Send claims.





3.    Click on created shared access policies and copy primary key for further use.


4.    Next is to create an API using the ‘Blank API’ template similar to what I have done below. Note the ‘Web service URL’ value is the base address of the Service Bus topic URL.



5.    Enter the Name and give web service URL of your service bus and click on create.


6.       Next Add operation based on your request like Post, Get Methods.



Before we add policy's create Named Values and our primary key is saskey, use this saskey as string key in our policy. 



Refer below screen after crated operation.



7.       Next step to added polices in added operation.

<policies>

    <inbound>

        <base />

        <cache-lookup-value key="apimqueuesend" variable-name="apimqueuesend" />

        <choose>

            <when condition="@(context.Variables.GetValueOrDefault&lt;string>("apimqueuesend") == null)">

                <cache-store-value key="crmsbsas" value="@{

                        string resourceUri = "https://dwproject.servicebus.windows.net/apimqueue";

                        string keyName = "apimqueuesend";

                        string key = "saskey";

                        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="apimqueuesend" variable-name="apimqueuesend" />

            </when>

        </choose>

        <set-backend-service base-url="https://dwproject.servicebus.windows.net" />

        <rewrite-uri template="apimqueue/messages" />

        <set-header name="Content-Type" exists-action="override">

            <value>vnd.microsoft.servicebus.yml</value>

        </set-header>

        <set-header name="Authorization" exists-action="override">

            <value>{{apimqueuesend}}</value>

        </set-header>

        <set-header name="BrokerProperties" exists-action="override">

            <value>@{

                    var json = new JObject();

                    json.Add("MessageId", context.RequestId);

                    return json.ToString(Newtonsoft.Json.Formatting.None);

                }</value>

        </set-header>

        <set-body>@{

                JObject json = context.Request.Body.As<JObject>(preserveContent: true);

                return JsonConvert.SerializeObject(json);

            }</set-body>

    </inbound>

    <backend>

        <base />

    </backend>

    <outbound>

        <base />

    </outbound>

    <on-error>

        <base />

        <return-response>

            <set-status code="200" reason="OK" />

        </return-response>

    </on-error>

</policies>

 9.       To test added policy please navigate to test in APIM section, please give required headers and json data and click on send.







10.       Finally Navigate to our queue and check whether message have received.




Reference Link:


https://joeblogs.technology/2021/07/posting-to-azure-service-bus-from-api-management/?utm_source=rss&utm_medium=rss&utm_campaign=posting-to-azure-service-bus-from-api-management

 

https://www.serverlessnotes.com/docs/expose-service-bus-queue-through-api-management

 

https://connectedcircuits.blog/2018/09/25/exposing-azure-service-bus-through-apim-generating-a-sas-token-and-setting-the-session-id/

















Comments

Popular posts from this blog

Open canvas app with Customize the command bar using command designer

How to implement approval in Teams using Adaptive Cards

Create email templates in dynamic 365 and send email using Power Automate

HTTP Request Methods

Duplicate Detection in Dynamics 365 using power apps.