I need to check if certain HTTPS proxies are working. To do so, I originally thought of using the following code:
var proxy = new WebProxy($"https://proxy-server:port");
var handler = new HttpClientHandler { Proxy = proxy };
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("https://base-address");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
try
{
var content = client.GetStringAsync(filepath).Result;
Console.WriteLine(content);
}
catch (Exception e)
{
Console.WriteLine("Failed. Reason: " + e);
}
}
If I try to access the base-address without the proxy, it works fine. Using the proxy I get an error saying I can only use HTTP or SOCKS proxies. The problem is, I wasn't able to find an alternate solution that supports HTTPS proxies.
You're getting the error because the WebProxy class in .NET does not support HTTPS proxies. However, you can use the HttpClientHandler's SslOptions property to configure the SSL/TLS settings.
var proxy = new WebProxy($"http://proxy-server:port");
var handler = new HttpClientHandler
{
Proxy = proxy,
SslOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true
}
};
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("https://base-address");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
try
{
var content = client.GetStringAsync(filepath).Result;
Console.WriteLine(content);
}
catch (Exception e)
{
Console.WriteLine("Failed. Reason: " + e);
}
}
Create a new instance of HttpClientHandler and set its Proxy property to a new WebProxy that represents the HTTP proxy server.
Set the SslOptions property to a new instance of SslClientAuthenticationOptions and configure the RemoteCertificateValidationCallback to return true, indicating that you want to accept any server certificate.
Create a new instance of HttpClient and pass the handler to its constructor.
Finally, use the client to send an HTTPS GET request to the base-address website.
Related
I'm trying to post a new Teams message. If I don't use proxy, pogram fails half start count with fail: Proxy auth required. If i try to use proxy, build fail by timeout (post timeout).
Maybe some fail in proxy settings?
using (var httpClientHandler = new HttpClientHandler
{
UseDefaultCredentials = true,
UseProxy = true,
Proxy = new WebProxy { UseDefaultCredentials = true }
})
{
using (var httpClient = new HttpClient())
{
var httpResponse = await httpClient.PostAsync(HookUri, StringContent);
}
}
I've trying to pass Windows Authentication to a WebProxy, so that a user doesn't have to type in his login data manually.
The use case is a proxy server which checks authentication against a LDAP/AD server, while the users have to change their password periodically.
I've got the following code:
private void button1_ClickAsync(object sender, EventArgs e) {
Url = "http://local.adress/test";
Execute();
}
private void button2_Click(object sender, EventArgs e) {
Url = "https://maps.googleapis.com/maps/api/timezone/json";
Execute();
}
private void Execute() {
var handler = new HttpClientHandler();
handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
handler.UseDefaultCredentials = true;
handler.UseProxy = true;
handler.Proxy = WebRequest.DefaultWebProxy;
handler.Proxy.Credentials = new NetworkCredential("mydomainuser", "mydomainpassword");
//handler.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
var client = new HttpClient(handler);
Task<string> response = TestConnection(client, Url);
}
private async Task<string> TestConnection(HttpClient client, string url) {
try {
using (HttpResponseMessage result = await client.GetAsync(url)) {
string res = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
Console.WriteLine("content: " + res);
return result.ToString();
}
} catch (Exception e) {
Console.WriteLine("error: " + e.Message);
return e.ToString();
}
}
When defining the credentials manually (as you can see in the Execute method), everythings works as expected. I've checked the proxy log files to be sure the request is really forwarded through the proxy.
Since it's my goal to spare the user to type in his probably periodically changing password, I've tried to pass the credentials via the CredentialCache.DefaultNetworkCredentials (I've also tried CredentialCache.DefaultCredentials). While executing the request the proxy logs an DENIED and my client returns HTTP error code 407.
Am I missing something obvious? I know there are countless questions on this topic but nothing seems to solve this problem.
You have to define proxy and main URL in code.
var TARGETURL = "http://en.wikipedia.org/";
HttpClientHandler handler = new HttpClientHandler()
{
Proxy = new WebProxy("http://127.0.0.1:8888"),
UseProxy = true,
};
try this.
handler.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
handler.Credentials = CredentialCache.DefaultNetworkCredentials;
ok so your webserivces uses windows authentication.
Your desktop client is working under your credential you need impersonation
https://learn.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.impersonate?view=netframework-4.8
check this if it works for you if it is basic authentication.
HttpClient client = new HttpClient(handler);
**var byteArray = Encoding.ASCII.GetBytes("username:password1234");**
**client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));**
I am trying to pull REST data from an API but I need to handle the calls to the API with some server side solution. I have tried using the following code
try
{
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(60);
var request = new HttpRequestMessage()
{
RequestUri = new Uri(string.Format("https://jsonodds.com/{0}{1}{2}", "api/odds/", "?source=", "3")),
Method = HttpMethod.Get,
};
request.Headers.Add("JsonOdds-API-Key", "your key");
HttpResponseMessage response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
String.Format("Success");
}
}
catch (Exception ex)
{ //log error }
I receive a 407() error. Any ideas or tips how to do this?
If you are going through a proxy server then you need to use a different constructor for HttpClient.
_httpClient = new HttpClient(new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy
{
Address = new Uri(proxyUrl),
BypassProxyOnLocal = false,
UseDefaultCredentials = true
}
})
{
BaseAddress = url
};
Replace proxyUrl with your proxy address then replacing the credential with those that are valid for your proxy. This example uses the default credentials, but you can pass a NetworkCredential to the WebProxy.
Hi I'm trying to implement simple http proxy service using Owin infrastructure. This proxy must authenticate user with windows authentication, pull user's properties from the enterprise AD, add this info as a cookie value into original request and then redirect request to the application on the Internet (lets call it External Application).
I'm using HttpClient to send request to the External Application.
However HttpClient does not fit well for this scenario. It seems that the only allowed way to send cookie using it is to put them into CookieContainer and set this CookieContainer as a property of HttpClientHandler. It's ok when you have single user but in case of a proxy service cookie values from different users will mix and overwrite each other.
Is there any way to set cookie or CookieContainer per request? Or maybe there is a better way to redirect requests?
P.S. Here is some code:
Initialization of http handlers:
private void RegisterRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Proxy",
routeTemplate: "{*path}",
handler: HttpClientFactory.CreatePipeline
(
innerHandler: new HttpClientHandler(),
handlers: new DelegatingHandler[]
{
new ProxyHandler()
}
),
defaults: new { path = RouteParameter.Optional },
constraints: null);
}
ProxyHandler
internal class ProxyHandler : DelegatingHandler
{
private readonly HttpClient _client;
public ProxyHandler()
{
var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Automatic};
_client = new HttpClient(handler);
}
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var forwardUri = new UriBuilder(request.RequestUri);
forwardUri.Host = "localhost";
forwardUri.Port = 23016;
forwardUri.Scheme = Uri.UriSchemeHttp;
request.RequestUri = forwardUri.Uri;
request.Headers.Host = forwardUri.Host;
//Explicitly null it to avoid protocol violation
if (request.Method == HttpMethod.Get || request.Method == HttpMethod.Trace)
request.Content = null;
try
{
var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
//Explicitly null it to avoid protocol violation
if (request.Method == HttpMethod.Head)
response.Content = null;
return response;
}
catch (Exception ex)
{
var response = request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
string message = ex.Message;
if (ex.InnerException != null)
message += ':' + ex.InnerException.Message;
response.Content = new StringContent(message);
Trace.TraceError("Error:{0}", message);
return response;
}
}
private void SetCookies(HttpRequestMessage request)
{
var container = new CookieContainer();
var authCookieValue = "2EF91D8FD9EDC594F2DB82";
var authCookie = new Cookie("cookieByProxy", authCookieValue);
var targetUri = new Uri("http://localhost:23016/");
container.Add(targetUri, authCookie);
var cookieHeader = container.GetCookieHeader(targetUri);
if (!string.IsNullOrEmpty(cookieHeader))
request.Headers.TryAddWithoutValidation("Cookie", cookieHeader);//Overwriting cookie header with custom values. However cookie values are ignored by HttpClient (both old and new)
}
}
Found solution here: enter link description here
The trick is in explicitly setting UseCookie flag of the HttpClientHandler to false.
var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Automatic, UseCookie = false };
I am using the HttpClient class to make GET requests, it works perfectly without proxy, but when I try to make a request thought a proxy server, it adds hostname in the path and there is also hostname in headers, so the full url is like http://google.comhttp://google.com/
The code:
static void GetSmth()
{
var baseAddr = new Uri("http://google.com");
var handler = new HttpClientHandler
{
AllowAutoRedirect = false,
UseCookies = true,
UseProxy = true,
Proxy = new WebProxy("111.56.13.168:80", true),
};
HttpClient client = new HttpClient(handler);
client.BaseAddress = baseAddr;
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "/");
var resp = client.SendAsync(request).Result;
}
Wireshark screenshot:
What is wrong with it?