I am trying to do a https GET to JustOneDB it works if I do it from the curl utility. But its NOT working from C#.
I get (400) Bad Request
I searched around and disabled security and all that but its still not working. Any ideas?
Has anyone done this w/ rest and JustOneDB?
This works along w/ all the other rest examples:
curl -k -XGET 'https://username:password#77.92.68.105:31415/justonedb/database/database name'
This DON'T work: I Dummied the string to remove my passcode.
public ActionResult JustOneDb()
{
///////////
HttpWebRequest request = null;
HttpWebResponse response = null;
try
{
String Xml;
//curl -k -XGET 'https://zn0lvkpdhdxb70l2_DUMMY_urshn5e7i41lb3fiwuh#77.92.68.105:31415/justonedb/database/n10lvkpdhdxei0l2uja'
string url = #"https://zn0lvkpdhdxb70_DUMMY_urshn5e7i41lb3fiwuh#77.92.68.105:31415/justonedb/database/n10lvkpdhdxei0l2uja";
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.Credentials = CredentialCache.DefaultCredentials;
// Ignore Certificate validation failures (aka untrusted certificate + certificate chains)
ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
// Get response
using (response = (HttpWebResponse)request.GetResponse())
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
Xml = reader.ReadToEnd();
}
return Content(Xml);
}
catch (Exception ee)
{
return Content(ee.ToString());
}
//////////////
ViewBag.fn = "*.xml";
return View();
}
Results:
System.Net.WebException: The remote server returned an error: (400) Bad Request. at System.Net.HttpWebRequest.GetResponse()
at Mvc3Razor.Controllers.MyXmlController.JustOneDb() ...
TIA
FxM :{
Instead of passing the username password in the url, you should create the correct credentials with "username" and "password". You might also want to consider using something like RestSharp instead of the raw WebRequest.
There was a mismatch with the certificate, which has been fixed. It is still self-signed, but now the hostname matches. We will be changing to use a fully signed certificate soon, but in the mean time please let me know if it works with just the self-signed override.
Ok, I copied the code, and the problem is that the HttpWebRequest library is not adding the authentication header in the original request. The solution is to insert the header manually, so if you add the following two lines after the 'request.Method = "GET" line (and remove the username/password from the URL string):
string authInfo = "zn0lvkpdhdxb70l2_DUMMY_urshn5e7i41lb3fiwuh";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
It should work correctly.
Related
I am making a call to a 3rd party service via https (using HttpWebRequest and sending a username, password in order to return a token which is then needed to make future requests for data). The service would only be required to list items on a public ASPNet website.
There will be no database involved so session or cookies would be storing the token.
To get the token I send a POST request which includes the username/password but I can see these details (username/password) in Fiddler (headers text tab I think but can confirm if anyone asks) - personally I thought I shouldn't? When I make a GET request to get the items I send the token and all works.
So am I supposed to encrypt the username/password somehow before making retrieving the token? If yes how would I do that?
I just feel that anyone could check the POST request and see what's going on. I could be wrong but happy to test any theories.
Edit 1
Here is the code i am sending the POST request. Please note the username and password along with the URL which is https
private string UsernamePassword()
{
string un = new JavaScriptSerializer().Serialize(new
{
User = "abc",
Password = "123"
});
return un;
}
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create("https://site.data.com");
wr.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate, br");
wr.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-GB,en-US;q=0.9,en;q=0.8");
wr.Headers.Add("Sec-Fetch-Site", "same-origin");
wr.Headers.Add("Sec-Fetch-Mode", "cors");
wr.Accept = "application/json";
wr.ContentType = "application/json";
byte[] data = null;
wr.Method = "POST";
data = Encoding.UTF8.GetBytes(UsernamePassword());
wr.ContentLength = data.Length;
wr.KeepAlive = true;
wr.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
try
{
using (Stream stream = wr.GetRequestStream())
{
stream.Write(data, 0, data.Length);
stream.Flush();
stream.Close();
}
using (HttpWebResponse httpResponse = (HttpWebResponse)wr.GetResponse())
{
var encoding = Encoding.GetEncoding(httpResponse.CharacterSet);
#germi is right. That's exactly what TLS/Https is for. The fact that you can see the content of your https request doesn't mean anyone can.
As long as your endpoint is using https (and not http), the exchange will happen over an encrypted channel. If you want to verify, install Wireshark and see for yourself.
I'm using Basic Authentication to retrieve xml order information from a website. The website endpoint url receives the authentication and then redirects to an url with the order information. I can successfully authenticate but not retrieve the order information (I get a blank page, with status 200. NOTE: This is the same result I get in a browser if I navigate directly to the redirected url without first go to the url which handles authentication). I believe this is because I need to handle the authentication cookie. However, as soon as I add a cookie container to my request, request.GetResponse() bombs with an internal server error 500.
I have tested the url endpoint using Fiddler, and I get the same result as when I don't add a cookie container to my request. Authentication is successful, and then the redirected page is blank with status code 200. (P.S. I can tell from Fiddler that the cookie is HttpOnly)
However, if I use a web browser and enter credentials at the initial url, it redirects to the order page with order content displayed.
Question 1: How can I determine (or further troubleshoot) if this is a problem with my code or with the order endpoint?
Question 2: If it's a problem with my code, how should I handle the cookie?
My code:
public void Main()
{
Uri endpointUri = new Uri(Dts.Variables["User::endpointUrl"].Value.ToString());
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endpointUri);
request.Method = "GET"; //I have also tried POST
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 1;
SetBasicAuthHeader(request, Dts.Variables["User::endpointUsername"].Value.ToString(), Dts.Variables["User::endpointPassword"].Value.ToString());
request.CookieContainer = new CookieContainer(); //If I comment out this line, the error does not occur, but I also don't see any order info.
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream dataStream = response.GetResponseStream();
Debug.WriteLine((new System.IO.StreamReader(dataStream)).ReadToEnd());
return;
}
}
public void SetBasicAuthHeader(WebRequest req, String userName, String userPassword)
{
string authInfo = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(userName + ":" + userPassword));
req.Headers["Authorization"] = "Basic " + authInfo;
}
The error:
The remote server returned an error: (500) Internal Server Error at
System.Net.HttpWebRequest.GetResponse()
i am looking to get the data from any given domain names SSL certificate. For example I want to put in any website address e.g. "http://stackoverflow.com" and my code would firstly check if an SSL certificate exists. If it does then I want it to pull out the expiry date of the certificate. [ i am reading Domainnames from DB ] Example :http://www.digicert.com/help/
i need to create a web service to check expiry date. how can i implement it?? - I have looked up loads of different things such as RequestCertificateValidationCallback and ClientCertificates etc. Since i am new to this, i am not sure what has to be done.
I could be completely wrong (hence why I need help) but would I create a HTTPWebRequest and then somehow request the client certificate and specific elements that way?
i tried the example provided #SSL certificate pre-fetch .NET , but i am getting forbitten 403 error.
Any help would be much appreciated - Thank you.
This is the code i have written which is throwing 403 forbidden error.
Uri u = new Uri("http://services.efi.com/");
ServicePoint sp = ServicePointManager.FindServicePoint(u);
string groupName = Guid.NewGuid().ToString();
HttpWebRequest req = HttpWebRequest.Create(u) as HttpWebRequest;
req.Accept = "*/*";
req.ConnectionGroupName = groupName;
using (WebResponse resp = req.GetResponse())
{
// Ignore response, and close the response.
}
sp.CloseConnectionGroup(groupName);
// Implement favourite null check pattern here on sp.Certificate
string expiryDate = sp.Certificate.GetExpirationDateString();
string str = expiryDate;
This works fine:
namespace ConsoleApplication1
{
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
class Program
{
static void Main()
{
ServicePointManager.ServerCertificateValidationCallback += ServerCertificateValidationCallback;
var request = WebRequest.Create("https://www.google.com");
var response = request.GetResponse();
Console.WriteLine("Done.");
Console.ReadLine();
}
private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine("Certificate expires on " + certificate.GetExpirationDateString());
return true;
}
}
}
You are getting a "403 forbidden" status because that's what the server returns when you access that page. I see the same thing when I browse to that Uri using IE. This status indicates that you don't have permission to access the Url, so perhaps you should try your code on a page that you have access to.
Also, you're unlikely to see a certificate on a http connection - you might want to try https instead.
If you need to download the certificate:
//Do webrequest to get info on secure site
var certName = "FileName";
var url = "https://mail.google.com";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Close();
//retrieve the ssl cert and assign it to an X509Certificate object
X509Certificate cert = request.ServicePoint.Certificate;
//convert the X509Certificate to an X509Certificate2 object by passing it into the constructor
X509Certificate2 cert2 = new X509Certificate2(cert);
string cn = cert2.GetIssuerName();
string cedate = cert2.GetExpirationDateString();
string cpub = cert2.GetPublicKeyString();
var path = Directory.GetCurrentDirectory() + string.Concat("\\", certName, ".der");
byte[] certData = cert2.Export(X509ContentType.Cert);
File.WriteAllBytes(path, certData);
Console.WriteLine("cert2.GetIssuerName :{0}", cert2.GetIssuerName());
Console.WriteLine("cert2.GetExpirationDateString :{0}", cert2.GetExpirationDateString());
Console.WriteLine("cert2.GetPublicKeyString :{0}", cert2.GetPublicKeyString());
.cs Sample File :https://gist.github.com/thedom85/6db200104c075310527aaef63b172253
I also recommend this site : https://www.simple-talk.com/dotnet/.net-framework/tlsssl-and-.net-framework-4.0/
I am getting The remote server returned an error: (400) Bad Request error while running the following code.
I am trying to upload xml file on the http server.
My xml file contains tag for the username,password and domain and when i am trying to connect is manually i am able to connect it,but using same credentials when i am trying to connect it through this code, i am getting 400 Bad Request error.
Please suggest me how to overcome this issue.
Thanks
`
public static void UploadHttp(string xml)
{
string txtResults = string.Empty;
try
{
string url = "http://my.server.com/upload.aspx ";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.KeepAlive = false;
request.SendChunked = true;
request.AllowAutoRedirect = true;
request.Method = "Post";
request.ContentType = "text/xml";
var encoder = new UTF8Encoding();
var data = encoder.GetBytes(xml);
request.ContentLength = data.Length;
var reqStream = request.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
WebResponse response = null;
response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
var str = reader.ReadToEnd();
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
HttpWebResponse err = ex.Response as HttpWebResponse;
if (err != null)
{
string htmlResponse = new StreamReader(err.GetResponseStream()).ReadToEnd();
txtResults = string.Format("{0} {1}", err.StatusDescription, htmlResponse);
}
}
else
{
}
}
catch (Exception ex)
{
txtResults = ex.ToString();
}
}`
Are you sure you should be using POST not PUT?
POST is usually used with application/x-www-urlencoded formats. If you are using a REST API, you should maybe be using PUT? If you are uploading a file you probably need to use multipart/form-data. Not always, but usually, that is the right thing to do..
Also you don't seem to be using the credentials to log in - you need to use the Credentials property of the HttpWebRequest object to send the username and password.
400 Bad request Error will be thrown due to incorrect authentication entries.
Check if your API URL is correct or wrong. Don't append or prepend spaces.
Verify that your username and password are valid. Please check any spelling mistake(s) while entering.
Note: Mostly due to Incorrect authentication entries due to spell changes will occur 400 Bad request.
What type of authentication do you use?
Send the credentials using the properties Ben said before and setup a cookie handler.
You already allow redirection, check your webserver if any redirection occurs (NTLM auth does for sure). If there is a redirection you need to store the session which is mostly stored in a session cookie.
//use "ASCII" or try with another encoding scheme instead of "UTF8".
using (StreamWriter postStream = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.UTF8))
{
postStream.Write(postData);
postStream.Close();
}
I actually connect in my univ to the network through a captive portal at this url https://secure.arubanetworks.com/cgi-bin/login, time ago I made a program to connect to it which worked perfect (C++ & libCurl), sending an HTTP POST with the needed "query string" such as username and password, but i think it was because there wasn't still the SSL, a X.509 Cert, that now seems to work with a GET instead of the POST that used before.
Pasting on Firefox the full url with the query string worked to me perfect, as it should, so i just tried to achieve that in a little C# program, but since i don't know what to do about the certificate (i asume there must be smth to do with it.. :P) it throws me a ProtocolError, and now i thought i should understand a bit about it first, so i'm interested in the code to achieve it, but also the way it works. :)
PS: Also would love if there's a way to set the account or the program (exe) as a callback, on the connection properties (my OS is Win7) so that once connected to the network im inmediatelly authenticated. :D
Thanks in advance for your time and help mates! ;)
Uri uri = new Uri(url + "?" + postData);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
req.Method = this.method;
// ToDo: Something doesn't work with the cert auth I guess
req.Proxy = null;
req.Credentials = CredentialCache.DefaultCredentials;
ServicePointManager.ServerCertificateValidationCallback +=
delegate(object sender, X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
return true;
};
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream responseStream = resp.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string responseFromServer = reader.ReadToEnd();
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
HttpWebResponse response = e.Response as HttpWebResponse;
if (response != null)
{
Console.WriteLine(e.ToString());
}
}
}
Try this for an https GET. For reference, it's related to but simpler than doing an https POST.
There's a difference if you need an asynch approach, but I don't think that's what you need. So, you still use HttpWebRequest object, but there's a difference after you get to the .method -- all you should need is to stuff your uri into the request, and grab the response. I don't think you should manually need to mess with the proxy or credentials.