I am new to C# and I hope you can help me with a problem I have not been able to figure out with authorization. This has been driving me nuts for weeks.
The task is simple, I have a server's URL that when I enter via basic authorization (just user + pass in a popup box) displays an XML document which I want to save to txt. The page has some self signed certificates as well.
For a little more info in case is useful, the server is a Cisco Call Manager and they run out of a closed Linux box (so changes in their coding are entirely not possible).
The triggering action is just a button that reads some txt from txtboxes for IP, user and password.
I have done a lot of research, tried many different codes and ways to request but they all have failed with the same code. At the end, the code I am trying to work with is below.
Here is my code:
string username = "user";
string password = "password";
var request = WebRequest.Create("http://serverIP/ast/ASTIsapi.dll?GetPreCannedInfo&Items=getServiceInfoRequest");
//I use this to bypass the certificate validation errors
ServicePointManager.ServerCertificateValidationCallback = delegate (object envio, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
//Convert the user:password into Base64
string encoded = System.Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + encoded);
var response = request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
var result = readStream.ReadToEnd();
File.WriteAllText("services.xml", result)
My problem is that I always get 401 not authorized. Interestingly, if I use the same authorization header to the same server but I use AXL code (to run SQL queries in example), it works fine without errors but this page is not accessible via AXL..
To test the page is able to accept that authorization via headers, I installed SOAPUI and run the URL with that header and the page displayed right away.
It seemed pretty straightforward but apparently I was wrong. Any assistance, guidance will be welcomed.
this is too long for a comment.
I think you're trying to request over SOAP API protocols. If so, you'll need to reconfigure your request to its requirements.
You can use SoapUI to do that easily. On your SoapUI, create a new request template, it'll generate simple request with its body and headers. Copy the body (usually will be xml) along with the request Headers, you can also use the request Log feature to debug it.
From that, you'll have a very good to start configuration that you can use in your code to setup the request.
You need also to ensure of your HTTP protocols such as if it's required HTTP or HTTPS, is it version 1 or version 1.1.. etc. As HTTP protocols sometimes differs from API to another, and without the correct protocols your request will be rejected.
you can do this :
string username = "user";
string password = "password";
var request = (HttpWebRequest)WebRequest.Create("http://serverIP/ast/ASTIsapi.dll?GetPreCannedInfo&Items=getServiceInfoRequest");
request.ContentType = "text/xml; charset=utf-8";
request.Accept = "text/xml";
request.Method = "POST";
request.Headers.Add("SOAPAction", "yourSoapAction"); // you can get it from SoapUI if you don't know it.
request.Headers.Add("Authorization", "Basic " + System.Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password)));
// OR you can use NetworkCredential
// request.Credentials = new NetworkCredential("user", "password");
// Simpler method to bypass the certificate validation errors
ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };
// Use this to set the HTTP Protocol Version
request.ProtocolVersion = HttpVersion.Version10;
/*
* Empty Standard Soap Envelope
*/
XNamespace soapenv = @"http://schemas.xmlsoap.org/soap/envelope";
XDocument body = new XDocument(
new XElement(soapenv + "Envelope",
new XAttribute(XNamespace.Xmlns + "soapenv", soapenv),
new XElement(soapenv + "Header"),
new XElement(soapenv + "Body")
));
// Since it's POST, it's required to have body, if SoapUI generated an empty body, then create empty XDocument and pass it.
using (var sw = new StreamWriter(request.GetRequestStream(), Encoding.UTF8))
using (var httpresponse = (HttpWebResponse)request.GetResponse())
using (var reader = new StreamReader(httpresponse.GetResponseStream()))
{
sw.Write(body);
File.WriteAllText("services.xml", reader.ReadToEnd().ToString());
}
for the body, you'll need to modify the body to fit Cisco Call Manager requirements.