none
Unable to set firewall rules using REST api

    שאלה

  • Hi.

    As part of our deployment tools, we have mechanisms in place for creating SQL Azure servers, and for existing ones, creating databases and creating the tables.

    These all work fine. I can use management certificates (located by thumbprint) and establish connections to the core management API endpoint, and the SQL Azure specific bits.

    However, when I create a SQL Azure server, I cannot programmatically set the firewall rules for it. I have followed the examples shown in the API guide, but I get 403 (Forbidden) when I try and issue the web request. I know the certificate is OK for that subscription because I used it to create the server in the first place.

    THe XML payload looks OK, and I am using PUT as the method. What else is likely to give me a 'forbidden' or is there something I need to do that I haven't?

    Steve

    יום חמישי 08 מרץ 2012 16:16

תשובות

  • Yes, I am using the certificates.

    I use XmlDocument to create the XML payload rather than hand-crafting a string, and other operations, such as 'create server' (like your example) work fine.

    I did examine the XML and noticed that in the FirewallRule element the namespace attributes are serialised in the sequence

    xsi:schemaLocations="..."

    xmlns="..."

    xmlns:xsi="..."

    but the XML is otherwise identical to the example in the online help. Bizarrely, I used a string which had the namespaces as shown in the example, and it worked. Go figure!

    So my problem is kind of solved, in that I can now set firewall rules, but I still don't understand why it wasn't working.

    However, I'm pragmatic, not obsessive, these days, so I can continue working on the rest of the tool.

    Thanks

    Steve

    יום שישי 09 מרץ 2012 10:31

כל התגובות

  • Hi,

    Do you ever add certificate in your request? Try to use the following code:

                string subscriptionID = "Your Subscription ID";
                string thrumbnail = "Your certificate thrumbprint";
                Uri requestUri = new Uri("https://management.database.windows.net:8443/" + subscriptionID + "/servers");
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                store.Open(OpenFlags.OpenExistingOnly);
                X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindByThumbprint, thrumbnail, false);
                store.Close();
    
                if (collection.Count != 0)
                {
                    X509Certificate2 certificate = collection[0];
                    HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(requestUri);
                    httpRequest.ClientCertificates.Add(certificate);
                    httpRequest.Headers.Add("x-ms-version", "1.0");
                    httpRequest.Method = "POST";
                    string Admin = "Your admin name";
                    string AdminPwd = "Your password";
                    string Location = "Your location";
                    string xmlBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                                      "<Server xmlns=\"http://schemas.microsoft.com/sqlazure/2010/12/\">\n" +
                                      "  <AdministratorLogin>" + Admin.ToString() + "</AdministratorLogin>\n" +
                                      "  <AdministratorLoginPassword>" + AdminPwd.ToString() + "</AdministratorLoginPassword>\n" +
                                      "  <Location>" + Location.ToString() + "</Location>\n" +
                                      "</Server>";
    
                    byte[] bytes = Encoding.UTF8.GetBytes(xmlBody);
                    httpRequest.ContentLength = bytes.Length;
                    httpRequest.ContentType = "application/xml;charset=utf-8";
                    using (Stream requestStream = httpRequest.GetRequestStream())
                    {
                        requestStream.Write(bytes, 0, bytes.Length);
                    }
                    HttpWebResponse httpResponse = httpRequest.GetResponse() as HttpWebResponse;
    
                        using (Stream stream = httpResponse.GetResponseStream())
                        {
                            using (XmlTextReader xmlReader = new XmlTextReader(stream))
                            {
                                while (xmlReader.Read())
                                {
                                    switch (xmlReader.NodeType)
                                    {
                                        case XmlNodeType.Element:
                                            if (xmlReader.Name == "ServerName")
                                            {
                                                if (xmlReader.Read() && (xmlReader.NodeType == XmlNodeType.Text))
                                                {
                                                    Console.WriteLine("NewServerName : {0}\n", xmlReader.Value.ToString());
                                                }
                                            }
                                            break;
                                    }
                                }
                            }
                        }
                    
                }

    Hope it can help you.

    Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework



    יום שישי 09 מרץ 2012 08:03
    מנחה דיון
  • Yes, I am using the certificates.

    I use XmlDocument to create the XML payload rather than hand-crafting a string, and other operations, such as 'create server' (like your example) work fine.

    I did examine the XML and noticed that in the FirewallRule element the namespace attributes are serialised in the sequence

    xsi:schemaLocations="..."

    xmlns="..."

    xmlns:xsi="..."

    but the XML is otherwise identical to the example in the online help. Bizarrely, I used a string which had the namespaces as shown in the example, and it worked. Go figure!

    So my problem is kind of solved, in that I can now set firewall rules, but I still don't understand why it wasn't working.

    However, I'm pragmatic, not obsessive, these days, so I can continue working on the rest of the tool.

    Thanks

    Steve

    יום שישי 09 מרץ 2012 10:31
  • Hi Steve,

    Gald to see your problem is solved, but if you still interested in this issue, i'd like to suggest you use Fiddler 2 to capture http requests from your application. For example, compare their request body properties to see if there is something difference between these two requests, also include status code and error message.

    Hope it can help you.


    Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework

    יום שישי 09 מרץ 2012 10:57
    מנחה דיון