I'm new at anglesharp. I tried the proxy change at the documentation but it didnt work.
Now i'm using this, it works well with webclient but it isnt working with AngleSharp.
The code i'm trying is ;
var handler = new HttpClientHandler()
{
Proxy = new WebProxy(String.Format("{0}:{1}", "myProxy", "myPort"), false),
PreAuthenticate = true,
UseDefaultCredentials = false,
};
var config = Configuration.Default.WithJs().WithCookies().WithDefaultLoader().With(handler);
//Create a new context for evaluating webpages with the given config
var context = BrowsingContext.New(config);
var document = await context.OpenAsync("https://api.ipify.org?format=json");
Console.WriteLine(document.DocumentElement.OuterHtml);
I'm not getting any error, proxy is not working thats it. I'm getting my original ip not the proxys.
But with WebClient it works well.
You just add something (handler, i.e., a HttpClientHandler instance) to AngleSharp's configuration - something that will not be used by anything in AngleSharp.
First of all AngleSharp's internal HTTP client is only a default client. For compatibility reasons AngleSharp cannot ship with HttpClient instead if uses HttpWebRequest. This also allows you setting a proxy.
Now if you want to use your code I suggest you use AngleSharp.Io (https://www.nuget.org/packages/AngleSharp.Io or https://github.com/AngleSharp/AngleSharp.Io). It's quite simple and straight forward:
var handler = new HttpClientHandler
{
Proxy = new WebProxy(String.Format("{0}:{1}", "myProxy", "myPort"), false),
PreAuthenticate = true,
UseDefaultCredentials = false,
};
var config = Configuration.Default
.WithRequesters(handler)
.WithDefaultLoader()
.WithJs()
.WithTemporaryCookies()
.WithDefaultLoader();
var context = BrowsingContext.New(config);
var document = await context.OpenAsync("https://api.ipify.org?format=json");
Console.WriteLine(document.DocumentElement.OuterHtml)
Only .WithRequesters(handler) has been added. This adds the requesters from AngleSharp.Io. By providing handler we can configure the HttpClient.
Hope that helps!
Related
I am trying to create a HttpClientHandler which contains the proxyUri and credentials like username and password without hardcoding them.
Below is the code:
HttpClientHandler clientHandler = new HttpClientHandler();
var proxy = HttpWebRequest.GetSystemWebProxy();
Uri proxyUri = proxy.GetProxy(new Uri("http://www.google.com"));
WebProxy proxyObject = new WebProxy(proxyUri);
proxyObject.UseDefaultCredentials = true;
clientHandler.Proxy = proxyObject;
clientHandler.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
The issues that I am encountering:
System.Net.CredentialCache.DefaultCredentials is null.
Is there an easier way of doing proxy.GetProxy(new Uri("http://www.google.com"))? From what I've research around, there used to be a method which is not deprecated. My issue with that line of code is that I don't wish to have hardcodations like that google link. Is there any other way of doing that?
I am using a library called SwaggerWcf to generate Swagger definitions for my application hosting a WCF REST API. I have finally made it work as I want it with the following code:
var swaggerHost = new WebServiceHost(typeof(SwaggerWcfEndpoint));
var endpoint =
new WebHttpEndpoint(
ContractDescription.GetContract(typeof(ISwaggerWcfEndpoint)),
new EndpointAddress("http://localhost/docs"))
{
AutomaticFormatSelectionEnabled = true,
FaultExceptionEnabled = true
};
// required to generate the swagger content
var e = new SwaggerWcfEndpoint();
swaggerHost.AddServiceEndpoint(endpoint);
var apiHost = new WebServiceHost(typeof(RestDataInterface));
var endpoint2 =
new WebHttpEndpoint(
ContractDescription.GetContract(typeof(IRestDataInterface)),
new EndpointAddress("http://localhost/api"))
{
AutomaticFormatSelectionEnabled = true,
FaultExceptionEnabled = true
};
apiHost.AddServiceEndpoint(endpoint2);
swaggerHost.Open();
apiHost.Open();
My question now is: is this the right way of doing it? As you can see I am creating two WebServiceHost instances. One for swagger and one for my actual API. While this seems to work fine, am I missing something? This API is intended to be fast but does not need to handle many concurrent users.
Thank you
The following code takes a target uri and gets its content as stream. Before the network call is made, it checks whether a proxy is required to access the target uri or not.
This works perfectly for .NET apps in full-framework (i.e. v4.8):
var targetUri = new Uri("...");
HttpClient client;
// get the system default web proxy ...
var proxyUri = WebRequest.DefaultWebProxy.GetProxy(targetUri);
// ... and check whether it should be used or not
var proxyAuthorityEqualsTargetAuthority = proxyUri?.Authority?.Equals(targetUri.Authority) == true;
var proxyRequired = !proxyAuthorityEqualsTargetAuthority;
if (proxyRequired)
{
var proxy = new WebProxy()
{
Address = proxyUri,
BypassProxyOnLocal = false,
UseDefaultCredentials = true
};
var httpClientHandler = new HttpClientHandler { Proxy = proxy };
client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
}
else
{
client = new HttpClient();
}
await client.GetStreamAsync(targetUri) ...
However it does not work within a .NET Core app:
Accessing WebRequest.DefaultWebProxy.GetProxy(targetUri) will throw a PlatformNotSupportedException:
Operation is not supported on this platform.
So I tried this line instead which is supported by .NET Core as well:
// deprecated: var proxyUri = new Uri(WebRequest.DefaultWebProxy.GetProxy(targetUri).AbsoluteUri);
var proxyUri = new WebProxy().GetProxy(targetUri);
However, the returning proxyUri.Authority does always return the targetUri now (both, in .NET and .NET Core) instead of the address to the proxy server like WebRequest.DefaultWebProxy.GetProxy(targetUri) does in .NET.
This way, proxyAuthorityEqualsTargetAuthority is always true and therefore, proxyRequired is always false. Accessing the target uri directly throws a 407 (Proxy Authentication Required).
Does anyone know how to get the address of the default web proxy in .NET Core?
Okay, I don't know what I missed as I tried this weeks ago. I tried again and everything seems fine.
With CredentialCache.DefaultCredentials, this short code works with both: .NET and .NET Core.
var targetUri = new Uri("...");
var handler = new HttpClientHandler();
handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
var client = new HttpClient(handler, disposeHandler: true);
await client.GetStreamAsync(targetUri) ...
I am trying to connect to a proxy via this piece of code using HttpClient.
i would like to connect to a proxy strictly using HttpClient, or if unable to. using any c# library as long as the task is achieved.
HttpClientHandler handler = new HttpClientHandler();
//setup web proxy and credentials
var webproxy =
new WebProxy("94.232.55.98", 8080)//ip and port number
{
UseDefaultCredentials = false,
Credentials = CredentialCache.DefaultCredentials
};
handler = new HttpClientHandler
{
Proxy = webproxy,
UseProxy = true,
PreAuthenticate = true,
UseDefaultCredentials = false
};
container = new CookieContainer();
handler.CookieContainer = container;
handler.UseCookies = true;
client = new HttpClient(handler);
//Query a url and get its contents, but the request was not using any proxy seemingly
HttpResponseMessage responseMessage = client.GetAsync("https://shop.shoprite.com/").Result;
Looking at the code i am in need of guidance on how to connect httpclient to a AU proxy, and how to possibly get a proxy with or without credentials and to make it work all together.
I am trying to access a website geo blocked only in Australia that is why im trying to use a proxy.
Thanks in advance!
EDIT:
I have retrieved my proxy from this site ( looking at AU proxies )
https://free-proxy-list.net/ and i get the first ip and put it on WebProxy, having 8080 as port number as an example
but it doesnt seem to work.
When i am about to request the site, i am having an error like this accessing a site that is geo blocked anywhere else except in australia.
It looks like your code is correct, however the host you are trying to connect to is not accessible through the proxy you are trying to use. You can get a more useful error message by altering the last few lines to utilise the EnsureSuccessStatusCode method. This will throw an exception if the status code is not 2XX.
using (var client = new HttpClient(handler))
using (var responseMessage = await client.GetAsync("http://shop.shoprite.com/"))
{
responseMessage.EnsureSuccessStatusCode();
responseMessage.Dump();
}
I have a Microsoft.Rest.ServiceClient generated with autorest. And I want to access a REST API secured with Windows Authentication and Basic Authentication.
The goal is to use Windows Authentication. I tried it as follows:
var handler = new HttpClientHandler
{
UseDefaultCredentials = true,
};
this.InitializeHttpClient(handler);
This does not work, I get:
System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
---> System.ComponentModel.Win32Exception: The target principal name is incorrect
When I use Basic Authentication it works.
this.Credentials = new BasicAuthenticationCredentials
{
UserName = Configuration.User,
Password = Configuration.Password
};
This setup of the ServiceClient is done in the constructor of
MyClient : Microsoft.Rest.ServiceClient
What do I need to add to the client to get Windows Authentication working?
Edited:
It looks like the problem is on server side. Settings in IIS.
The client would work as expected.
This basically reiterates what's already covered in the OP and by #Anders, in my preferred syntax...
var windowsAuthHandler = new HttpClientHandler { UseDefaultCredentials = true };
var webApiUri = new System.Uri("https://localhost:8080");
var apiClient = new MyAutoRestClient(webApiUri ,windowsAuthHandler);
If you're skimming, the OP seems to indicate this doesn't work, when, indeed it does. But, as the OP later states, be sure to start with IIS to make sure it's configured right
I use a similar solution for passing on Windows credentials, and it works nicely.
The only difference is that I use the constructor overload of ServiceClient that takes a HttpClientHandler instance, rather than calling InitializeHttpClient() and it looks something like this:
public class MyClient : ServiceClient<MyClient>
{
public MyClient() : base(new HttpClientHandler { UseDefaultCredentials = true }) {}
}
However, the part of your 401-message that says "The target principal name is incorrect" looks suspicious. Your problem may arise from some issues in your AD-configuration rather than in the ServiceClient-configuration.
#bkwdesign has right
var credentials = new Microsoft.Rest.BasicAuthenticationCredentials();
var handler = new System.Net.Http.HttpClientHandler() { UseDefaultCredentials = true };
var uri = new Uri("http://your-rest-api:8008");
var svc = new WebApplication1Client(uri, credentials, handler);
//WebApplication1Client : ServiceClient<WebApplication1Client>, IWebApplication1Client
This is the way how to pass credentials from MVC to WebAPI Windows Authentication or impersonate credentials
Maybe other options:
var handler = new HttpClientHandler() { Credentials = CredentialCache.DefaultCredentials };
var handler = new HttpClientHandler() { Credentials = CredentialCache.DefaultNetworkCredentials };