C# Basic Authentication from curl request - c#

I have curl request and i'd like create analog to C#. Bat all my attempts have failed. I tried everything I could find in google. This description API https://github.com/onlinerby/onliner-b2b-api/blob/master/docs/oauth20.md
this curl
$process = curl_init("https://b2bapi.onliner.by/oauth/token");
curl_setopt($process, CURLOPT_HTTPHEADER, array('Accept: application/json'));
curl_setopt($process, CURLOPT_USERPWD, "204da9b95e2480a3455f:7a4bbb61262fdf41d410645292a0489ba752c6b9");
curl_setopt($process, CURLOPT_POST, 1);
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($process, CURLOPT_POSTFIELDS, array('grant_type' => 'client_credentials'));
$result = curl_exec($process);
curl_close($process);`
this my c# code
string url = "https://b2bapi.onliner.by/oauth/token";
WebClient client = new WebClient();
client.Headers["Accept"] = "application/json";
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes("204da9b95e2480a3455f:7a4bbb61262fdf41d410645292a0489ba752c6b9"));
client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
var result = client.UploadString(url, "grant_type=client_credentials");`
please help me, i am lost a lot time ...

Related

How to POST request for authorization token from filemaker API in c#

I am hitting a POST request to a FileMaker API to get an authorization token but its throwing web exception. How can I fix it?
I have tried it in java. Now I am trying it in c# .NET framework 4.6.1
private static void GetToken(string username, string password)
{
try
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://exchange.furniflair.com/fmi/data/v1/databases/FurniflairDB/sessions");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
var bytes = Encoding.UTF8.GetBytes("dataapi:Data4me");
string temp = Convert.ToBase64String(bytes);
httpWebRequest.Headers.Add("Authorization", "Basic ZGF0YWFwaTpEYXRhNG1l");
string token;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
token = streamReader.ReadToEnd();
}
}
catch (WebException ex){}
}
I expect the output to be the authorization token in response, but I am getting only exceptions like httpWebException.
If it helps you set the headers correctly, here is an example that works using PHP.
$Post_Json = '{}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$URL);
curl_setopt($ch, CURLOPT_PORT,443);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout after 30 seconds
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $Post_Json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$result=curl_exec ($ch);
This comes from: https://schwarzsoftware.com.au/blogentry.php?id=19
Also ensure that the Data API is turned on in the FileMaker Admin server console, and enabled for the FileMaker file you are trying to access, and access priviliges enabled for that user in the FileMaker file.

Https Post with .crt and .key

I am sorry if it is duplicate. I see a couple of post over the internet about this topic. But do not get any appropriate solution. I am working at nopcommerce 4.0, which is run on the .net core but the targeted framework is 4.x.x. I am developing a payment plugin which needs secure connection with .crt and .key files. The payment method provider sends a php file which is working as expected. Below is the sample code
function ProcessRequest($curl_post_data,$service_url,$proxy,$proxyauth)
{
$output = '';
$certfile = '/createorder.crt';
$keyfile = '/createorder.key';
$cert_password = '';
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $service_url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch, CURLOPT_SSLCERT, getcwd() . $certfile );
curl_setopt( $ch, CURLOPT_SSLKEY, getcwd() . $keyfile );
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curl_post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$output = curl_exec($ch);
if (curl_error($ch)) {
echo $error_msg = curl_error($ch);
}
$cblcz = json_decode($output, true );
return $cblcz;
}
$proxy ="";
$proxyauth ="";
$postDatatoken = '{
"password": "123456Aa",
"userName": "test"
}';
$serviceUrltoken ="";
$serviceUrltoken= 'https://sandbox.thecitybank.com:7788/transaction/token';
$cblcz = ProcessRequest($postDatatoken,$serviceUrltoken,$proxy,$proxyauth);
I can not convert this curl to http post. I tried below link
PHP/Curl-SSL operations alternative in C# and others but do not get any work around.
Do not work. For openssl it is throwing dependency are not loaded. Here is my c# code
try
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
var certPath = Path.Combine(CommonHelper.MapPath("~/Plugins/Payments.CityBankApi/"), "createorder.crt");
var keyPath = Path.Combine(CommonHelper.MapPath("~/Plugins/Payments.CityBankApi/"), "createorder.key");
string certificateText = File.ReadAllText(certPath);
string privateKeyText = File.ReadAllText(keyPath);
ICertificateProvider provider = new CertificateFromFileProvider(certificateText, privateKeyText);
//X509Certificate certificate = provider.Certificate;
string accessTokenUrl = "https://sandbox.thecitybank.com:7788/transaction/token";
var requestUrl = new Uri(accessTokenUrl);
var request = (HttpWebRequest)WebRequest.Create(accessTokenUrl);
request.ContentType = "application/json";
request.Method = "POST";
request.ClientCertificates.Add(provider.Certificate);
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = "{\"userName\":\"test\"," +
"\"password\":\"123456Aa\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
catch (Exception ex)
{
throw ex;
}
Your code seems correct. But make sure you have valid certificate. If the certification is not correct it will through an exception. Check your exception message and try to detect exact error. OR post your error message here.
moreover you should add
request.ServerCertificateValidationCallback = (e,r,c,n) => true;

Converting PHP CURL query to C#'s HttpWebRequest

I'm using HttpWebRequest in C# to do a POST to a particular API. The problem is that the system on the other end does not receive the body of the request. More so, when trying to send the request via tools like Postman, I have the same issue. The only thing that seems to work is a PHP implementation, detailed below.
My best guess is that I'm missing some header or another that the PHP sets automatically.
Has anybody encountered a similar problem/does anyone have a clue what I'm missing?
Both implementations below.
<?php
error_reporting(E_ALL);
$url = <<the APIs url>>
$hash = base64_encode('<<username>>:<password>>');
$data = [];
$username = <<username>>
$password =<password>>
$data = array(array(
"id" => "9999999",
"status" => 1,
<<rest of the formated data>>
));
$requestData = array(
'data' => $data,
'hash' => $hash
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($requestData));
$result = curl_exec($ch);
// $result = json_decode($result, true);
curl_close($ch);
die('done :'.$result);
?>
And here the C# implementation:
var httpWebRequest = (HttpWebRequest)WebRequest.Create(this.api_url);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = true;
httpWebRequest.Date = DateTime.Now.Date;
httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
httpWebRequest.Headers.Add("Authorization", "Basic " + Base64Encode(userName + ":" + password));
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
tring requestResult = null;
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
requestResult= streamReader.ReadToEnd();
}
If you are posting JSON data, you should set the content type to application/json.

c# equivalent of md5 in PHP

I have a code which looks like this, It's basically a JSON request which I need to pass to the server and code in PHP looks like this:
<?php
$client_secret= '';
$data= array(
'email' => '**********',
'password' => '******',
'client_id' => '*******'
);
$api_url='******';
$json_data=json_encode($data);
$signature_string = md5($json_data . $client_secret);
$post_data = 'signature='.$signature_string.'&data='.urlencode($json_data);
$curl = curl_init($api_url);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
$result = curl_exec($curl);
print_r($result);
curl_close($curl);
?>
And this works fine in PHP. So now I'm trying to translatet this code into C#.
What I did so far is:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
string client_secret = "*****";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"email\":\"******\"," +
"\"password\":\"******\"}" +
"\"client_id\":\"******\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
string resp = string.Empty;
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
resp = streamReader.ReadToEnd();
}
return resp;
Basically I now have my data in JSON format. What now I need to do is replicate the PHP's md5 function to create a MD5 hash out of my client_secret string + JSON string which was created in previous step and then simply post the data string to server.
Can someone help me out with this ?

Https POST from Php to C#

I have to make a post to a third party https url to get data procesed and sent back. And all I have as an example is this:
$signature= foo_string;
$data_to_post = json_dictionary;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base_url);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_HTTPHEADER,array("JSON-Signature: $signature"));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_to_post);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
As we work with ASP .NET C# 2.0, I have to port this, but I get always a not autenticated error.
Here is what I'm doing:
HttpWebRequest q = (HttpWebRequest)WebRequest.Create(Host + ":" + Port);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications);
q.Method = "POST";
q.Headers.Add("JSON-Signature:" + GetSignature(data));
q.ContentType = "application/json";
q.UseDefaultCredentials = false;
q.Credentials = new NetworkCredential(user,pwd, Host);
byte[] buffer = UTF8Encoding.UTF8.GetBytes(data);
q.ContentLength = data.Length;
Stream oStream = q.GetRequestStream();
StreamWriter oWriter = new StreamWriter(oStream);
oWriter.Write(buffer);
oWriter.Close();
HttpWebResponse reps = q.GetResponse() as HttpWebResponse;
I've read all SO questions I can find about this, but I don't get any improvements. Thanks in advance!
Well, one thing you're doing wrong is assuming that the length in bytes is the same as the length in characters. You should use buffer.Length for the content length. You're also calling StreamWriter.Write with a byte array. You shouldn't do that - you should just use the stream, as you've already done the encoding:
byte[] buffer = Encoding.UTF8.GetBytes(data);
q.ContentLength = buffer.Length;
using (Stream stream = q.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
}
Now, that won't solve the authentication issue. You may find that just setting PreAuthenticate solves that though:
q.PreAuthenticate = true;
If that doesn't work, I suggest you run WireShark and look at the differences between the request through Curl and the request from .NET.
I think you should not supply the host in the authentication...
q.Credentials = new NetworkCredential(user,pwd);
Which would be something like:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Host + ":" + Port);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications);
request.Method = "POST";
request.Headers.Add("JSON-Signature:" + GetSignature(data));
request.ContentType = "application/json";
request.UseDefaultCredentials = false;
request.Credentials = new NetworkCredential(user, pwd);
byte[] buffer = UTF8Encoding.UTF8.GetBytes(data);
request.ContentLength = buffer.Length;
using (Stream oStream = request.GetRequestStream()) {
oStream.Write(buffer, 0, buffer.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
// load data from response here
}
Also you should avoid assigning the service point validation delegate on each request, this may slow down the requests increasingly because the validation is performed multiple times, and it's also kind of a memory leak.
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
Here is how you add that CURLOPT_USERPWD in Asp.Net:
private async Task<string> Execute(string url, string query, string user, string pasword)
{
HttpClient httpClient = new HttpClient();
var baseUri = new Uri(url, UriKind.Absolute); // e.g. http://somedomain.com/endpoint
Uri request = new Uri(baseUri, query); // with query e.g. http://somedomain.com/endpoint?arg1=xyz&arg2=abc
// Add a new Request Message
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, request);
// add headers -> CURLOPT_USERPWD equivalent
var encodedStr = Convert.ToBase64String(Encoding.Default.GetBytes(string.Format("{0}:{1}", user, password)));
var authorizationKey = "Basic" + " " + encodedStr; // Note: Basic case sensitive
requestMessage.Headers.Add("Authorization", authorizationKey);
// if POST - do this instead
// content
//HttpContent content = new StringContent(jsonContent); // string jsonContent i.e. JsonConvert.SerializeObject(YourObject);
//requestMessage.Content = content;
//requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
// execute
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
var responseString = await responseMessage.Content.ReadAsStringAsync(); // reads it as string;
// if json and you need to convert to an object do this
// var myresponse = JsonConvert.DeserializeObject<YourMappedObject>(responseString);
return responseString;
}

Categories

Resources