How to create Shared Access Signature for Service Bus?

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

Shared Access Signature (SAS) for Service Bus introduces the new authentication and authorization model. With SAS, authentication and authorization can be
done without of need to involve Access Control Service which is the default authentication and authorization model when working with Service Bus.
I already shortly described this model in this post.

In this post I will provide two WORKING examples which show how to create SAS token in .NET and in JavaScript, respectively.

Creating of SAS token in .NET

Following code shows how to create SB-SAS token in C#.

        var sasToken = createToken("http://yournamespace.servicebus.windows.net/yourqueue”
       
"device_send_listen", "…z67vRa9Tk8TJo0sErXlL6jg7P6dFA=");

       // Create REST request and append the token to ‘Authorization’ header . . .

        /// <summary>
       
/// Code  for generating of SAS token for authorization with Service Bus
       
/// </summary>
       
/// <param name="resourceUri"></param>
       
/// <param name="keyName"></param>
       
/// <param name="key"></param>
       
/// <returns></returns>
       
private static string createToken(string resourceUri, string keyName, string key)
        {           
           
TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
           
var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); //EXPIRES in 1h
           
string stringToSign = HttpUtility.UrlEncode(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(CultureInfo.InvariantCulture,
           
"SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
               
HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);

           
return sasToken;
        }


To use this token you will have to create the REST request and append the token to ‘Authorization’ header. Fortunately nobody
in .NET space will do that, because .NET SDK provide much simpler way to deal with SAS tokens. However the sample above
shows how the token can be created if you need to talk to Service Bus by using of REST. For example, the code above helped me to
to understand how to make a token and to implement the same code in JavaScript.

Following example shows how to create SAS token implicitly in a much simpler way by using .NET SDK.

        public static void SasTokenSample()
        {
        

           
Uri runtimeUri = ServiceBusEnvironment.CreateServiceUri("sb", "yournamespace", string.Empty);
           
MessagingFactory mf = MessagingFactory.Create(runtimeUri,
               
TokenProvider.CreateSharedAccessSignatureTokenProvider("device_send_listen"
               
"AsjoWKeRn5fiyELz67vRa9Tk8TJo0sErXlL6jg7P6dFA="));

            QueueClient sendClient = mf.CreateQueueClient(m_qName);

           
//Sending message to queue.
           
BrokeredMessage helloMessage = new BrokeredMessage("Hello, Service Bus!");
            helloMessage.MessageId =
"Hello SAS token Message";
            sendClient.Send(helloMessage);
        }


 

Creating of a SAS token in JavaScript


When you work in JavaScript, there is no Service Bus JS-SDK, which helps to create the token. For this reason I implemented a sample
which creates the SAS token for Service Bus in Java Script.
Before you start you will have to include Google’s crypto helpers HMAC-SHA256 and Base64.

  <script type="text/javascript"
 
 src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/hmac-sha256.js"></script>

  <script type="text/javascript"
 
src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/enc-base64-min.js"></script>


Here is the JS code for SAS token creation:

    var m_ServiceNamespace = “yournamespace”;
    var m_SasKey = "…ErXlL6jg7P6dFA=";         
   
var m_SasKeyName = "device_send_listen";

 
// Function which creates the Service Bus SAS token.
var getToken = function (entityPath) {

       
var uri = "http://" + m_ServiceNamespace +
       
".servicebus.windows.net/" + entityPath;

       
var endocedResourceUri = encodeURIComponent(uri);

       
var t0 = new Date(1970, 1, 1, 0, 0, 0, 0);
       
var t1 = new Date();
       
var expireInSeconds =  + (31*24*3600) + 3600 +
       (((t1.getTime() - t0.getTime()) / 1000) | 0);

       
var plainSignature = utf8Encode(endocedResourceUri +
       
"\n" + expireInSeconds);

       
var hash = CryptoJS.HmacSHA256(plainSignature, m_SasKey);
       
var base64HashValue = CryptoJS.enc.Base64.stringify(hash);

       
var token = "SharedAccessSignature sr=" + endocedResourceUri + "&sig=" +
        encodeURIComponent(base64HashValue) +
"&se=" + expireInSeconds + "&skn=" +
        m_SasKeyName;

       
return token;
    }

  
   
var utf8Encode = function (s) {
       
for (var c, i = -1, l = (s = s.split("")).length,
            o = String.fromCharCode; ++i < l;
            s = (c = s.charCodeAt(0)) >= 127 ? o(0xc0 | (c >>> 6)) +
            o(0x80 | (c & 0x3f)) : s
        );
       
return s.join("");
    }
   



And finally, following sample shows hot to send the message to Service Bus. When the user click on the button the message is read
from HTML TextBox named ‘btnSend’ and serialized as JSON.

   sendMessage: function (entityPath, body, contentType, callback) {
           
var securityToken = getToken(entityPath);
           
var entityUri = "https://" +
            m_ServiceNamespace +
"." + this.environment + "/" + entityPath;
           
var sendUri = entityUri + "/messages/?timeout=60";
           
var xmlHttpRequest = new XMLHttpRequest();

            xmlHttpRequest.open(
"POST", sendUri, true);
           
xmlHttpRequest.setRequestHeader('Content-Type', contentType);
            xmlHttpRequest.setRequestHeader(
"Authorization", securityToken);
           
            xmlHttpRequest.onreadystatechange = function () {
               
if (this.readyState == 4) {

                   
var messagingResult;
                   
// Expects HTTP-201 (Created) when the
                    // message is entered in the queue / topic.

                   
if (this.status == 201) {
                        messagingResult =
                      
new MessagingResult("Success", this.status, null, this.response);
                    }
                   
else {
                        messagingResult =
                       
new MessagingResult("Failure", this.status, null, this.response);
                    }

                    callback(messagingResult);
                }
            };

            xmlHttpRequest.send(body);
        },



            $(
"#btnSend").click(function () {
            
    
              
msg = {
"message": txtMsg.value, "id": 1234};
             

               SB.sendMessage(queue,  JSON.stringify(msg) ,
                
"application/json", function (messagingResult) {
                  
var res = messagingResult;
               });
            });

In my following posts, I will describe how to receive this message on Windows RT and Windows system 32 (also know as Windows Desktop).


Posted Oct 17 2013, 07:32 AM by Damir Dobric

Comments

Damir Dobric Posts wrote Windows Azure Service Bus: Sending the message to queue and topic with JavaScript
on 03-26-2014 21:46

IAs you probably know the easiest way to send the message to the queue or topic is to use .NET SDK. When

Making REST calls to send data to an Azure EventHub | abgoswam's tech blog wrote Making REST calls to send data to an Azure EventHub | abgoswam&#039;s tech blog
on 10-14-2016 3:23

Pingback from  Making REST calls to send data to an Azure EventHub | abgoswam's tech blog

developers.de is a .Net Community Blog powered by daenet GmbH.