Quantcast
Channel: Service Bus forum
Viewing all articles
Browse latest Browse all 1916

Rest - SB STS Token does not allow me to create queue

$
0
0

Hi,

I am using WSB 1.0 on my local machine.  I am the admistrator of this machine.

I am just trying to follow a simple Rest SB scenario. Create a queue, put a brokered message on that queue, and then read it out via Http.

I am following this article (which is for the azure sb).

http://msdn.microsoft.com/en-us/library/windowsazure/hh416754.aspx

In this article they get the token from Azure ACS:

using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;

namespace Microsoft.ServiceBus.Samples
{
    class Program
    {

        static string serviceNamespace;
        static string baseAddress;
        static string token;
        const string sbHostName = "servicebus.windows.net";
        const string acsHostName = "accesscontrol.windows.net";


        static void Main(string[] args)
        {

            Console.Write("Enter your service namespace: ");
            serviceNamespace = Console.ReadLine();

            Console.Write("Enter your issuer name: ");
            string issuerName = Console.ReadLine();

            Console.Write("Enter your issuer secret: ");
            string issuerSecret = Console.ReadLine();

            baseAddress = "https://" + serviceNamespace + "." + sbHostName + "/";
            try
            {
                // Get a SWT token from the Access Control Service, given the issuerName and issuerSecret values.
                token = GetToken(issuerName, issuerSecret);

                string queueName = "Queue" + Guid.NewGuid().ToString();

                // Create and put a message in the queue using the SWT token.
                CreateQueue(queueName, token);
                SendMessage(queueName, "msg1");
                string msg = ReceiveAndDeleteMessage(queueName);

                string topicName = "Topic" + Guid.NewGuid().ToString();
                string subscriptionName = "Subscription" + Guid.NewGuid().ToString();
                CreateTopic(topicName);
                CreateSubscription(topicName, subscriptionName);
                SendMessage(topicName, "msg2");

                // Wait for messages to post:
                //System.Threading.Thread.Sleep(500);
                Console.WriteLine(ReceiveAndDeleteMessage(topicName + "/Subscriptions/" + subscriptionName));

                // Get an Atom feed with all the queues in the namespace
                Console.WriteLine(GetResources("$Resources/Queues"));

                // Get an Atom feed with all the topics in the namespace
                Console.WriteLine(GetResources("$Resources/Topics"));

                // Get an Atom feed with all the subscriptions for the topic we just created
                Console.WriteLine(GetResources(topicName + "/Subscriptions"));

                // Get an Atom feed with all the rules for the topic and subscritpion we just created
                Console.WriteLine(GetResources(topicName + "/Subscriptions/" + subscriptionName + "/Rules"));

                // Delete the queue we created
                DeleteResource(queueName);

                // Delete the topic we created
                DeleteResource(topicName);

                // Get an Atom feed with all the topics in the namespace, it shouldn't have the one we created now
                Console.WriteLine(GetResources("$Resources/Topics"));

                // Get an Atom feed with all the queues in the namespace, it shouldn't have the one we created now
                Console.WriteLine(GetResources("$Resources/Queues"));
            }
            catch (WebException we)
            {
                using (HttpWebResponse response = we.Response as HttpWebResponse)
                {
                    if (response != null)
                    {
                        Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
                    }
                    else
                    {
                        Console.WriteLine(we.ToString());
                    }
                }
            }

            Console.WriteLine("\nPress ENTER to exit.");
            Console.ReadLine();
        }    private static string GetToken(string issuerName, string issuerSecret)
        {
            var acsEndpoint = "https://" + serviceNamespace + "-sb." + acsHostName + "/WRAPv0.9/";

            // Note that the realm used when requesting a token uses the HTTP scheme, even though
            // calls to the service are always issued over HTTPS
            var realm = "http://" + serviceNamespace + "." + sbHostName + "/";

            NameValueCollection values = new NameValueCollection();
            values.Add("wrap_name", issuerName);
            values.Add("wrap_password", issuerSecret);
            values.Add("wrap_scope", realm);

            WebClient webClient = new WebClient();
            byte[] response = webClient.UploadValues(acsEndpoint, values);

            string responseString = Encoding.UTF8.GetString(response);

            var responseProperties = responseString.Split('&');
            var tokenProperty = responseProperties[0].Split('=');
            var token = Uri.UnescapeDataString(tokenProperty[1]);

            return "WRAP access_token=\"" + token + "\"";
        }  // Uses HTTP PUT to create the queue
        private static string CreateQueue(string queueName, string token)
        {
            // Create the URI of the new Queue, note that this uses the HTTPS scheme
            string queueAddress = baseAddress + queueName;
            WebClient webClient = new WebClient();
            webClient.Headers[HttpRequestHeader.Authorization] = token;

            Console.WriteLine("\nCreating queue {0}", queueAddress);
            // Prepare the body of the create queue request
            var putData = @"<entry xmlns=""http://www.w3.org/2005/Atom""><title type=""text"">" + queueName + @"</title><content type=""application/xml""><QueueDescription xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"" /></content></entry>";

            byte[] response = webClient.UploadData(queueAddress, "PUT", Encoding.UTF8.GetBytes(putData));
            return Encoding.UTF8.GetString(response);
        }

    }
}


However I have replaced this method with this call to the on premise SBSTS like so:

(as described here  - http://msdn.microsoft.com/en-us/library/windowsazure/jj193003%28v=azure.10%29.aspx)

public static void Usage()
{
    string token = GetOAuthAccessToken(new 
        Uri("https://<hostname.domain.com>:9355/<namespace> /"), "user@corp.domain. com", "<password>", TimeSpan.FromMinutes(10)); 
}
public static string GetOAuthAccessToken(Uri namespaceBaseAddress, string userName, string userPassword, TimeSpan timeout)
{
    const int ServicePointMaxIdleTimeMilliSeconds = 50000;
    const string OAuthTokenServicePath = "$STS/OAuth/";
    const string ClientPasswordFormat = "grant_type=authorization_code&client_id={0}&client_secret={1}&scope={2}";

    Uri requestUri = new Uri(namespaceBaseAddress, OAuthTokenServicePath);
    string requestContent = string.Format(CultureInfo.InvariantCulture, 
        ClientPasswordFormat, HttpUtility.UrlEncode(userName), 
        HttpUtility.UrlEncode(userPassword), 
        HttpUtility.UrlEncode(namespaceBaseAddress.AbsoluteUri));
    byte[] body = Encoding.UTF8.GetBytes(requestContent);

    HttpWebRequest request = WebRequest.Create(requestUri) as HttpWebRequest;
    request.ServicePoint.MaxIdleTime = ServicePointMaxIdleTimeMilliSeconds;
    request.AllowAutoRedirect = true;
    request.MaximumAutomaticRedirections = 1;
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = body.Length;
    request.Timeout = Convert.ToInt32(timeout.TotalMilliseconds, 
        CultureInfo.InvariantCulture);

    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(body, 0, body.Length);
    }

    string rawAccessToken = null;
    using (var response = request.GetResponse() as HttpWebResponse)
    {
        using (Stream stream = response.GetResponseStream())
        {
            using (var reader = new StreamReader(stream, Encoding.UTF8))
            {
                rawAccessToken = reader.ReadToEnd();
            }
        }
    }

    string simpleWebToken = string.Format(CultureInfo.InvariantCulture, 
        "WRAP access_token=\"{0}\"", rawAccessToken);
    return simpleWebToken;
}

Now when I try and call the create queue with this SBSTS token added to the AuthorisationHeader of the request, I get an 401 Unauthorised Response.

This is despite me being Admin on my machine, and despite me being able to create queues via the Service Bus Explorer no problem. 

In addition when I create a queue from a console app using 

  namespaceManager.CreateQueue(QueueName);

It works just fine.

So I wondered is OAuthToken approach the correct way to authenticate over Http? 

All I want to do is create and post a message to a queue from a console app over http.

Can anyone help please?

Thanks very much







Viewing all articles
Browse latest Browse all 1916

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>