On one of my recent projects, a client application was required to place a message onto an Azure Service Bus using an HTTP endpoint rather than 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.
- The first step of this solution is to create an Azure Service Bus with a queue called 'apimqueue'.
Please refer below screenshot.
![Azure Service Bus through APIM and generating a SAS Token]()
![Azure Service Bus through APIM and generating a SAS Token]()
2. Next, click on created queue, navigate to Shared access policy, and add' apimqueuesend' with only Send claim.
![Azure Service Bus through APIM and generating a SAS Token]()
![Azure Service Bus through APIM and generating a SAS Token]()
3. Click on created shared access policies and copy the primary key for further use.
![Azure Service Bus through APIM and generating a SAS Token]()
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.
![Azure Service Bus through APIM and generating a SAS Token]()
5. Enter the Name, give your service bus's web service URL, and click on create.
![Azure Service Bus through APIM and generating a SAS Token]()
6. Add operation based on your request, like Post, and Get Methods.
![Azure Service Bus through APIM and generating a SAS Token]()
Refer below screen after the created operation.
![Azure Service Bus through APIM and generating a SAS Token]()
7. Next step is to add policies to added operation.
![Azure Service Bus through APIM and generating a SAS Token]()
8. Add the below policy as shown in the above screen.
<policies>
<inbound>
<base />
<cache-lookup-value key="apimqueuesend" variable-name="apimqueuesend" />
<choose>
<when condition="@(context.Variables.GetValueOrDefault<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}&sig={1}&se={2}&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 the APIM section. Please give the required headers and JSON data and click on send.
![Azure Service Bus through APIM and generating a SAS Token]()
![Azure Service Bus through APIM and generating a SAS Token]()
10. Finally, Navigate to our queue and check whether the message has been received.
![Azure Service Bus through APIM and generating a SAS Token]()