Acessing a WebService (HTTPS) that requires a certificate via WCF in C# - c#

I'm the client machine, and the server I'm trying to access is a program which I'll be providing support to (I'm a new 3rd party program) and I need to send then some data.
They use HTTPS but I couldn't connect with this:
public void StartProcess()
{
BasicHttpsBinding binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
// - They said they don't require credentials
EndpointAddress address = new EndpointAddress("https://www.outsideservice.com/services/C001");
OutsideServiceClient client = new OutsideServiceClient(binding, address);
DataToSend data = new DataToSend();
// - Filling up whatever data I need to send, omitted
try
{
client.StartProcess(data);
}
catch (Exception ex)
{
// ex = Could not establish trust relationship for SSL/TLS secure channel
}
}
They already have other 3rd party programs accessing their servers.
I don't have a very good knowledge on how certificates work (other than the basic reading on MSDN).
After questioning how I can access their servers, I got the reply:
" already access our servers via https, just access the machine, download the certificate and use on your client machine."
After googling around how I do this, I tried to access https://theirURL.com/certsrv from here, but I get Resource Not Found error.
From what I could understand from how certificates work, I must obtain a certificate from them, double click it, install on my machine (or the machine running the code to connect to them) to be able to connect right?
Or is there something that I have to do on my end to be able to connect?

"I must obtain a certificate from them, double click it, install on my machine (or the machine running the code to connect to them) to be able to connect right?"
This is the correct way to do things, however to get things up and running you can use this bit of code:
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
I usually like to wrap this in code that doesn't apply this on a release build so that production actually has to have the certificate installed properly as follows:
#if (!Release)
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
#endif
I believe you should be able to put this anywhere you like, such as the Global.asax.cs or right before the call is made.

Related

C# call an API through proxy using HttpWebRequest

I want to make an API call (outside my organization domain) in my existing application, the network team has told me to set up a proxy config - only then it'd have the ability to go to the internet.
Dev has the ability to go to the internet without referencing the proxy setup.
In my dev environment, it is working fine since the ports are open, how to configure a proxy for UAT environment so that it can hit the new target on the internet?
proxy IP is given by the network team for Non-prod: 12.XXX.XXX.0 Port 80
and also how to check:
if the above proxy is alive?
once it is configured how to check if the request is going through the
proxy because I just have dev server access where all ports are open,
how would I check if it is configured correctly so that once deployed
on UAT it works fine?
The HttpWebRequest has a proxy property:
var myWebRequest = (HttpWebRequest)WebRequest.Create("url");
myWebRequest.Proxy = new WebProxy("host", 80);
try
{
var response = myWebRequest.GetResponse();
//...
}
catch (WebException e)
{
// handling issues
}
If a request fails, an exception will be thrown that you can handle in catch block.

C# How to Access local network (192.168.x.x) within Docker containers

This is my first post here, I've looked across the internet in order to solve this issue but have no idea how to do this, as i am new to docker and not that great at networking (saying kindly).
I need a way to access my host machines internal network IP which has been forwarded to a port that connects to a proxy server. so essentially 192.168.x.xx:5000 => someproxyserver.com
now when setting up the SOCKS5 on my local machine or even in C# it is able to connect and it works.
but this is not the case with docker, again i am complete noob at docker, i have tried many things, but i can't seem to get my docker container to connect to the socks5 server.
I even tried to run the docker container with --network=host but i get an error (no route to host)
Ideally i would not want to use --network host as i have many other containers connecting to a external network.
var settings = new ProxySettings() {
Host = localIp,
Port = port
};
using (var proxyClientHandler = new ProxyClientHandler<Socks5>(settings)) {
using (var httpClient = new HttpClient(proxyClientHandler)) {
var response = await httpClient.GetStringAsync("https://api.ipify.org?format=json");
}
}
this is the C# code which i am using to connect to the SOCKS5 server.
When using --network=host
without --network=host
I managed to make this work somehow, without including any run commands, i believe this was failing due to my firewall blocking access, it was weird as i did allow access to it, however after restarting my computer earlier on, it worked :) so yeah if anyone stumbles across this, just remember to make sure your firewall isn't blocking access to docker

Hosting a C# WebSocket Server on Elastic Beanstalk

I’ve written a WS server from scratch and I’m trying to host it on AWS Elastic Beanstalk service. However, I’ve only figured a way to add it to a web project (that can be hosted on EB) by tacking it on with a thread on startup.cs:
Thread thr = new Thread(() =>
{
var ws = new WebsocketServer();
});
thr.IsBackground = true;
thr.Start();
To my delight and surprise, I was able to successfully test this locally and it works perfectly fine, but when put on EB I am unable to connect to anything (even though I am 99% certain I’m sending requests to the appropriate URL). I’ve tried adding the port I’ve specified but nothing helps.
I’m using a TcpListener initialized like this:
TcpListener server = new TcpListener(IPAddress.Parse(“127.0.0.1”), 443);
server.Start();
And accept clients with a TcpClient like so:
TcpClient client = new TcpClient();
client = server.AcceptTcpClient();
Now based on my experience I assume that the connection is working properly but EB simply does not automatically set it up for public access. Is there any way to do this? Would using the same port as the web app help? (If so, how do I set/see what port it does use?). Since WS is initiated with a HTTP request, is there possibly a way to establish a connection using a Controller method of the format:
[Route("ws")]
[HttpGet]
public async Task<IActionResult> ConnectWS()
{
return await AddClient();
}
I have no Load Balancer set up for the EB environment I'm using.
Lastly, if this is a bad practice or infeasible, is there another AWS service I could use to host the server that’s easy to set up for public connections?
Thank you!
Looking at your code, you need to open up traffic on port 443. Depending on your Elastic Beanstalk configuration ( with load balancer? or without load balancer? update your question with this please ) you are close to getting it to work on AWS.
These high level steps will get you there:
Get a cert. For testing you can install openSSL on your local dev machine and create a self-signed cert. AWS has a guide on how to do this. Note: don't use self-signed certs on your live production system. When your site goes public, obtain a catchy name and a real cert to front your service.
(If no load balancer skip to step 3) Go to Certification Manager in your AWS console. There is a big blue button, Import Certficiate. Click this. Open the server.crt file from step 1 with your favorite text editor and paste the contents in the top box with the label: Certificate body. Then open the privatekey.cer file from step 2 with your favorite text editor and paste the contents in the second box with the label: Certificate private key. Click Review and Import and make sure everything is ok
If you have a load balancer, follow the steps from this AWS guide on how to open up 443 on it.. If you don't have a load balancer and it is just a single instance, its a bit more complicated as you have to do it via configuration files. Follow the steps here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance.html
Try it out and reply back if you have updates to your question with more config specifics. I think you are close to working it out and getting it running on AWS.

The Underlying Connection Was Closed. Could not establish trust relationship with remote server

I'm trying to connect to a web service through HTTPS.
I had success configuring a self-signed certificate by referring to this link Setting up IIS with HTTPS Binding
Now I added some code to the handheld device to call the web service. I had referred to several websites and saw the same code.
public class MyPolicy : ICertificatePolicy
{
public bool CheckValidationResult(
ServicePoint srvPoint
, X509Certificate certificate
, WebRequest request
, int certificateProblem)
{
//Return True to force the certificate to be accepted.
return true;
} // end CheckValidationResult
} // class MyPolicy
I also added this line before calling the web service
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();
But I am still getting the error: Could not establish trust relationship with remote server.
Any clues on what's wrong with the code?
The handheld code probably doesn't trust your self-signed certificate. You have to override the default certificate handling to allow it. When calling from a browser, this triggers a warning dialog which allows you to trust the self-signed certificate in a specific case.

How to access web service on ServiceStack from android device?

I have an android application that's supposed to send a request to a simple HelloWorld C# webservice I made on ServiceStack but I am not able to connect. My application crashes when I try to connect. Here is my code on Eclipse, trying to access the ServiceStack service:
String base = "http://192.168.1.7:62938/json/reply/Hello?Name=";
String str = editTextField.getText().toString();
StringBuilder url = new StringBuilder(base + str);
String result = "";
HttpClient hc = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url.toString());
HttpResponse r = hc.execute(httpget);
int status = r.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
JSONObject o = new JSONObject(data);
result= o.getString("result");
}
My C# service code for ServiceStack:
//Request DTO
public class Hello
{
public string Name { get; set; }
}
//Response DTO
public class HelloResponse
{
public string Result { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
//Can be called via any endpoint or format, see: //http://mono.servicestack.net/ServiceStack.Hello/
public class HelloService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Helloooo, " + request.Name };
}
}
My service works fine on my laptop when I go to localhost:62938/json/reply/Hello?Name="arbitraryName"
but it does not work when I try to replace localhost with my laptop's ip address and access the service from an android device. It also does not work if I replace localhost with my IP address and try it on my browser on my laptop. Note: I want to make it work from a real android device, not an emulator.
Is there something different with ServiceStack services where I cannot access it normally from another device? I have already tried opening port 62938 and it did not work.
I appreciate any guidance. Thank you.
It also does not work if I replace localhost with my IP address and try it on my browser on my laptop.
If you have tried accessing the ServiceStack service through the local IP address of 192.168.1.7 in your computer's web browser and it is also unreachable, then the issue isn't isolated to Android.
This is issue is likely the result of one or more of these problems:
Check you are listening on the correct IPs:
Your ServiceStack service isn't configured to listen for requests on any other interfaces other than localhost. Select your relevant hosting option:
Self Hosting:
This can happen if you are self hosting and you have configure the app host to start with appHost.Start("http://localhost:62938/");. You would need to replace localhost with a + symbol to have it listen on all local addresses.
IIS Express:
By default IIS Express is used by Visual Studio during development, unless manually configured to use IIS, and is restricted to localhost requests only. You should see this answer as to how to configure IIS Express to allow non-local access as well.
This tutorial by Scott Hanselman is also very good, and provides great step-by-step instructions for configuring IIS Express.
IIS:
You can confirm the IP addresses that you server is configure to listen on by following these instructions. They provide instructions for both IIS6 and IIS7+.
Firewall:
Your computer may have a firewall preventing you accessing that port, or accepting outside traffic. Note your firewall may be built into antivirus software you run. You should add an exception rule for http traffic on port 62938.
Correct IP:
You are trying to access on 192.168.1.7. You should confirm that IP address is in fact correct. Most home networks are configured to provide a dynamic IP address by the network router. The IP address may have changed since you last checked it. You should try running a ping to the IP from your development machine.
Until you can successfully access the service through your web browser on your development machine, at the local network IP starting 192.168.1.X then I wouldn't attempt to access from Android. It's not an Android issue if other systems can't access your service also.
I hope that helps. If you provide more information about your specific environment, I may be able to provide more specific instructions. If I had to guess, I would say IIS Express issue.
Edit:
Now that you can access the service in the web browser of your android device but not in the application, we know the service is remotely accessible. This means your connectivity issue is isolated now to your application. The first thing I would check, is that your application has permission to make network requests. In your AndroidManifest.xml you need to ensure that android.permission.INTERNET is included
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
If you have that permission then you should be able to make the request successfully. If it continues to fail, then the reason need to be diagnosed from the exception that is causing the application to crash. In which case you should wrap the data request in a try { ... } catch(Exception exception) { } and log the exception.
As the Android emulator is considered to be running on a different device, to refer to the loopback IP (127.0.0.1) on our local development machine we need to use the special 10.0.2.2 alias.
Other special device IP's can be found in Andorid's documentation.

Categories

Resources