Connecting to a .NET webservice via a SOCKS5 proxy - c#

I'm attempting to connect through a SOCKS5 proxy to a webservice. Currently, my app.config is as follows:
<system.net>
<defaultProxy enabled="true" >
<proxy proxyaddress="http://xxx.xxx.xxx.xxx:yyyy" bypassonlocal="True" />
</defaultProxy>
</system.net>
This works fine for http proxies, however it just doesn't connect to SOCKS5 ones. I've googled far and wide for an answer and just can't find anyone that's solved this problem, even though I've found the question a couple of times. Anyone have any idea on how I can do this?

Apparently Microsoft did not build SOCKS proxy support into their web classes (see http://windows-tech.info/13/f17246e7dd4a8a2b.php)
I too am in a situation where I'd like to use the built-in .NET web functionality with a SOCKS5 proxy, and have not found any satisfactory solution. I guess my next step is to obtain the source of the .NET classes either through Reflector or from the Mono codebase and refactor it to use the ProxySocket class mentioned in the above link.
This is more work than I wanted, but seems to be the only way.

In .NET 6 you can do it easily as follows:
var proxy = new WebProxy
{
Address = new Uri("socks5://localhost:8080")
};
//proxy.Credentials = new NetworkCredential(); //Used to set Proxy logins.
var handler = new HttpClientHandler
{
Proxy = proxy
};
var httpClient = new HttpClient(handler);
or when you can inject IHttpClientFactory (recommended way):
In your ConfigureServices method:
Services.AddHttpClient("WithProxy")
.ConfigurePrimaryHttpMessageHandler(() =>
{
var proxy = new WebProxy
{
Address = new Uri("socks5://localhost:8080")
};
return new HttpClientHandler
{
Proxy = proxy
};
});
Then in your controller or anywhere you can inject IHttpClientFactory object, create a new httpClient (with configured proxy) instance as follows:
httpClient = httpClientFactory.CreateClient("WithProxy");
Here is a more detailed description:
https://dotnetcoretutorials.com/2021/07/11/socks-proxy-support-in-net/

If you are able to use HttpClient, you can use SocksSharp.
I just followed the example and it worked for me.
var settings = new ProxySettings()
{
Host = "xxx.xxx.xxx.xxx",
Port = yyyy
};
using (var proxyClientHandler = new ProxyClientHandler<Socks5>(settings))
{
using (var httpClient = new HttpClient(proxyClientHandler))
{
var response = await httpClient.GetAsync("http://example.com/");
}
}

In theory you can inherit the webservice class and override GetWebRequest and GetWebResponse. Then you may be able to use this c# socks class http://www.codeproject.com/Articles/5954/C-class-for-connecting-via-a-SOCKS-Proxy-Server and convert the webrequest to sockets and back again.
The quickest solution I have been able to find is to set a system wide socks proxy using WideCap. This routes all traffic on the machine via the socks proxy server.

Related

Can I call a WCF endpoint from ASP.Net Web API?

I have a web api with controller methods that use rest http(post/get calls).
Clients consume this API with normal httpclient calls and I pass an http response back.
My use case is I have a legacy method that needs to make a call to another server. This method currently uses WCF and contract binding but I don't want to use WCF in this API project.
Is there a way that I can still call these methods using just WEB API or do I have to mix architectures (Web api with WCF)?
Here is the normal method call
First I initialize the proxy
var proxy = GetAccountProxy();
public static AcountClient GetAccountProxy()
{
var client = new AccountClient();
client.ClientCredentials.ClientCertificate.SetCertificate(...);
return client;
}
I connect to a method on the other server through the proxy
var accountInfo = proxy.GetAccountInfo(xmlAccount);
public string AccountInfo(string sXml){
AccountLookup val = new AccountLookup();
val.Body = new AccountLookupRequestBody();
val.Body.XML = sXML;
AccountLookupResponse retVal = ((AccountLookupResponse)(this)).AccountLookup(val);
return retVal;
}
In my webconfig the endpoints look like this
<endpoint address="https://www.mylookup.com/AccountLookupWS/AccountLookupWS.svc/wshttp" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IAccountLookupWS" contract="AccountLookupWS.IAccountLookupWS" name="WSHttpBinding_IAccountLookupWS1" />
So my question is can I just call this endpoint using a normal rest httpclient call and have the same result?
Uri baseUrl = new Uri("https://www.mylookup.com/AccountLookupWS/AccountLookupWS.svc/wshttp");
IRestClient client = new RestClient(baseUrl);
IRestRequest request = new RestRequest("GetAccountInfo", Method.GET)
request.AddParameter("XmlAccount", sXml);
IRestResponse<dynamic> response = client.Execute<dynamic>(request);
if (response.IsSuccessful)
{
response.Data.Write();
}
else
{
Console.WriteLine(response.ErrorMessage);
}
Console.WriteLine();
In general it is possible to access wcf with webrequest, but it depends on the wcf service implementation. Check out the WebGet and/or WebInvoke attributes https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.web.webgetattribute?view=netframework-4.8 and start from there.
It is work to be done on WCF side, after it is done properly, you can access your wcf as normal rest services.
It depends on your WCF server bindings. You see, HTTP/s protocol implementation is just possible module of WCF, a part, just like any other protocol out there - it is just called binding. Different bindings means same bindings should be on client side, otherwise they don't understand each other.
For example if server tells:
use gzip on my data which I send over wire
then I xor my data with 666 if first bit is set true
then use SSL to protect it
then send it over TCP
Then client should do the same thing in reverse. This is WCF and it's flexibility for you which opened hell gates for researchers and developers.
As I said, if your server supports HTTP bindings, without extra stuff - you are good. Use http client or billion other HTTP classes. If not - port your server protocol bindings to NET Core and use them.

Default proxy in .net core 2.0

I saw couple of questions asked about core 2.0 on how to make HttpClient to use default proxy configured on the system. But no where found right answer. Posting this question hoping someone who might have encountered this issue might have found the solution by now.
In .net framework versions I've used the following configuration in my web.config and it worked for me.
<system.net>
<defaultProxy useDefaultCredentials="true"></defaultProxy>
</system.net>
But in .net core 2.0 where I've make a web request to external api from my company's intranet my code is failing with 407, proxy authentication required.
After little bit of research I am of the opinion that it is not possible to make your HttpClient to use default proxy settings configured via WPAD in IE. Can someone correct my understanding here?
On this page of https://github.com/dotnet/corefx/issues/7037
It is said as follows :
"The default for HttpClientHandler.UseProxy property is true. And the default value of HttpClientHandler.Proxy is NULL which means to use the default proxy."
But I don't observe this behavior.
Update:
I am finally able to call external web api by specifying the proxy server address and then making the HttpClient call. Still wondering how to use default proxy setup in IE.
using (var handler = new HttpClientHandler {
Credentials = new System.Net.NetworkCredential(user, password, domain),
UseProxy = true,
Proxy = new System.Net.WebProxy(new Uri("http://xxxxxxx:8080"), true)
})
{
handler.Proxy.Credentials = new NetworkCredential("xxxx", "yyyyy", "cccccc");
using (var httpClient = new HttpClient(handler))
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri(destinationUrl),
Method = HttpMethod.Post
};
request.Content = new StringContent(requestXml, Encoding.UTF8, "text/xml");
HttpResponseMessage response = await httpClient.SendAsync(request);
Task<Stream> streamTask = response.Content.ReadAsStreamAsync();
}
}
If any one interested in finding out how I was able to find out the proxy server was, I wrote the following code in .net 4.0 and found out the proxy used.
var proxy = WebRequest.GetSystemWebProxy();
var url = proxy.GetProxy(new Uri("http://google.com"));
Thanks
I hope this is the answer you're looking for: Default Proxy issues #28780
If you simply want to use the default system proxy and need to pass default credentials to that proxy (because the proxy is an authenticated proxy) during HTTP requests, then do this:
var handler = new HttpClientHandler();
handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
var client = new HttpClient(handler);

Is there any way to hide/override real IP while using anonymous or transparent proxy?

Is there any way to hide/override real IP while using anonymous or transparent proxy?
I want to send empty in HTTP_X_FORWARDED_FOR. I am using C# Winform. Below is the code snippet.
WebClient wc = new WebClient();
//wc.Headers["HTTP_X_FORWARDED_FOR"] = "0.0.0.0"; --Not working
wc.Proxy = new WebProxy(ipproxy, port);
string t = wc.DownloadString("https://www.leaky.org/ip_tester.pl");
The goal is to send completely anonymous request. The proxies I am using is not brought from any website, they are collected from random sites. It would be great if someone also mention any good site of working proxies.
Thanks
Yes. You can use ProxySharp to generate/get proxy servers to use for your request.
https://github.com/m-henderson/ProxySharp
After you install the ProxySharp nuget package, you can get a random anonymous proxy to use with your request. Like this:
WebClient wc = new WebClient();
var proxyServer = Proxy.GetSingleProxy();
wc.Proxy = new WebProxy(proxyServer);
string t = wc.DownloadString("https://www.leaky.org/ip_tester.pl");
It also has different methods for getting, renewing, and popping proxies from the queue that it generates.
Yes. I built ProxySharp to do exactly what you are trying to do.
ProxySharp has a method that will get you a random anonymous proxy to use with your web request. Check out the repo for more info https://github.com/m-henderson/ProxySharp
The X-Forwarded-For header is generally added by the proxy server, not the client. If you put something there, the proxy server will overwrite or append to it.

How to determine if an HttpResponseMessage was fulfilled from cache using HttpClient

What is the equivalent to WebResponse.IsFromCache when using HttpClient and HttpResponseMessage?
Is there some HTTP header in the response that I can look at?
FYI: The Windows.Web.Http HttpClient (a similar API targetted at Windows 8.1 app development) does include an HttpResponseMessage.Source field that specifies where the result came from (common values are "cache" and "network").
The Windows.Web.Http classes are usable from C# and other .NET languages, from C++, and from JavaScript (when running as a WwaHost app like from the Windows app store).
Can I ask what you're trying to achieve? Are trying to avoid caching?
The reason for asking is I've looked at the source code for HttpClient (specifically HttpClientHandler) and the source for HttpWebResponse and I dont believe you can get this information from the headers.
HttpClient/HttpClientHandler does use HttpWebResponse internally however it does not expose all properties from HttpWebResponse :
private HttpResponseMessage CreateResponseMessage(HttpWebResponse webResponse, HttpRequestMessage request)
{
HttpResponseMessage httpResponseMessage = new HttpResponseMessage(webResponse.StatusCode);
httpResponseMessage.ReasonPhrase = webResponse.StatusDescription;
httpResponseMessage.Version = webResponse.ProtocolVersion;
httpResponseMessage.RequestMessage = request;
httpResponseMessage.Content = (HttpContent) new StreamContent((Stream) new HttpClientHandler.WebExceptionWrapperStream(webResponse.GetResponseStream()));
//this line doesnt exist, would be nice
httpResponseMessage.IsFromCache = webResponse.IsFromCache;// <-- MISSING!
...
}
So your options the way I see it are:
a) Look at the source code for HttpWebRequest to determine the logic for IsFromCache and retrofit this somehow into HttpClient (this may not even be possible, depends on what the logic actually does/needs)
b)ask the ASP.NET team for this property to be included with HttpResponseMessage. either directly as a property or perhaps they could 'keep' the HttpWebResponse
Neither of these options are that great sorry, hence my original question, what are you trying to acheive?
I've been struggling with this scenario recently as well.
What I needed was an integration test to verify that:
Responses for a newly created resource had the correct headers set by the server.
Subsequent requests for that resource were fulfilled from the client-cache.
Responses for an existing resource had the correct headers set by the server as well.
What I ended up doing was a twofold check:
A non-caching HttpClient to check the initial response:
new WebRequestHandler
{
AllowAutoRedirect = true,
UseCookies = true,
CookieContainer = new CookieContainer(),
CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Refresh)
};
var client = new HttpClient(handler)
and a second HTTP client to check the client-side cache:
new WebRequestHandler
{
AllowAutoRedirect = true,
UseCookies = true,
CookieContainer = new CookieContainer(),
CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default)
};
var client = new HttpClient(handler)
To verify the source of response messages I compare the HttpResponseMessage.Headers.Date values from steps 1 and 2 (which will be the same if the response came from the client cache). For my third step I can just re-use the client from the first step and append an arbitrary string to the URL.
Disclaimer: this applies to .NET Framework 4.7 and ignores best practices concerning HttpClient usage but is seems to do the trick for me in my test suite. An explicit property like the one mentioned above would be preferable but does not seem to be available. Since the last reply here is already a few years old there might be better ways to handle this, but I couldn't think of one.

Sending an API CAll with PayPal SOAP API

Ok, so I have the service reference in my .NET project. And yes I know that you now have access to proxy classes.
But in the past, I am used to doing this via an HttpWebRequest object using NVP, but never tried using the WSDL and sending a SOAP request this way.
I'm not quite sure which object to use to send the request. Not sure where to start here. I've looked at the docs but seen no good examples out there for .NET and PayPal.
Other than a WSDL vs. sending an HttpWebRequest via a NVP API and querystring params, I really do not understand if there's a difference in how you send the request. It's all just over Http so can't you use HttpWebRequest also over a SOAP API (using WSDL)?
You start by generating a service reference from the metadata: Right click on the project -> Add Service Reference and point to the WSDL url: https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl
This will generate proxy classes to the current project which could be used to send requests:
using (var client = new PayPalAPIInterfaceClient())
{
var credentials = new CustomSecurityHeaderType
{
Credentials = new UserIdPasswordType
{
Username = "username",
Password = "password"
}
};
var request = new AddressVerifyReq
{
AddressVerifyRequest = new AddressVerifyRequestType
{
Street = "some street",
Zip = "12345"
}
};
var response = client.AddressVerify(ref credentials, request);
}

Categories