I'm trying to get some resources from the website using simple HttpClient and HttpClientHandler classes. When i use Http, it works well but in case of Https it doesn't work. The following code is my settings:
var url="https://www.someurl.com";
var proxy = new WebProxy("127.0.0.1", 8888);
WebRequest.DefaultWebProxy = proxy;
htmlHandler = new HttpClientHandler();
htmlHandler.UseProxy = true;
htmlHandler.Proxy = proxy;
I also changed settings of .exe.config file and it didn't worked. I should note that just one entry in fiddler was shown:
Is the Tunnel line in the picture you included a reference to the site to which the .NET client is trying to send traffic? Or is it unrelated? (What is the Process column?)
What do you see on the LOG tab when traffic is sent to Fiddler?
The most likely explanation is that the Fiddler Root Certificate is not trusted by the account in which the .NET client application runs. Fiddler allows you to trust the Fiddler Root certificate on a machine-wide basis which will resolve such issues.
Related
I am in the process of building a WCF client for a SOAP HTTPS webservice in .Net Core 2.1.
The service provider has supplied a .key and a .cert file which I have converted to a .p12 file using openssl. By adding this to a keystore I am able, through SoapUI, to successfully sent a request to the webservice (no other authentication than the certificate is required).
To do the same operation in .Net Core I have added a Connected Service to my project through the WCF wizard in Visual Studio. This service is based on the supplied service contract (WSDL file). I have then installed the .p12 certificate locally on my PC and I am using the following code to make the request. "MyService" is the connected service.
var binding = new BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
var endpoint = new EndpointAddress("https://x.x.x.x:8300/MyService.asmx");
var channelFactory = new ChannelFactory<MyService>(binding, endpoint);
channelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
channelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication()
{
CertificateValidationMode = X509CertificateValidationMode.None,
RevocationMode = X509RevocationMode.NoCheck,
TrustedStoreLocation = StoreLocation.LocalMachine
};
channelFactory.Credentials.ClientCertificate.SetCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindByIssuerName,
"xxxxxxxxxxxxxxxxxxxxxxxxxx");
var service = channelFactory.CreateChannel();
ExecuteResponse response = service.Execute(new ExecuteRequest());
When running this code I am getting the following error:
System.ServiceModel.Security.MessageSecurityException: 'The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate'.'
The strange thing is that I am allowed to make the request if I use the HttpClientHandler which tells me that there must be a mismatch between the underlying structure of the two implementations.
Anyone who knows how I can fix this error?
The certificate might just be used to establish the trust relationship between the client-side and the server-side.
For making a successful call to the service, we should keep the binding type between the client-side and the server-side consistent. Therefore, I would like to know the automatically generated client-side configuration by Adding service reference, please post the System.servicemodel section located in the appconfig of the client project.
If the server authenticates the client-side with a certificate, the error typically indicates the trust relationship has not established yet between the client-side and the server-side.
On the client-side, we should install the server certificate in the LocalCA. On the server-side, we should install the client certificate in the LocalCA certificate store.
Feel free to let me know if the problem still exists.
I'm having some issues implementing a client that talks to a WCF service. It's a WCF hosted by another company so I don't have access to its code. I used the Connected Service provider tool in Visual Studio to generate the client code so that I could make requests and everything works fine on my local machine. I am having an issue on our development environment where I receive the following error if I try to make a request with the client:
The HTTP request was forbidden with client authentication scheme 'Anonymous'
I've been looking at the client code (it's a lot of code) which is generated by the Provider tool and I think it may have something to do with the following block of code.
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
return result;
This more linked to firewall rules within corporate network.
I had same issue using non authorized proxy but got resolved secured proxy with ntlm ClientCredentialType
This error typically indicates that the WCF server authenticates the client-side with a certificate. The error will occur when the trust relationship between the server and the client have not been established yet.
In general, we need to provide client credential to be authenticated by the server so that be able to call the service. As for what kind of credentials need to be provided, it depends on the binding information on the server-side.
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
Namely, the above errors have indicated that the server authenticates the client with a certificate.
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
About authenticating the client with a certificate, you could refer to the below link for details.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-certificate-authentication
Feel free to let me know if there is anything I can help with.
Thanks for all the suggestions. This was actually just caused by a firewall rule that was setup within our organisation. Once that was removed the code worked as expected.
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
Security is provided using HTTPS. The service must be configured with SSL certificates. The SOAP message is protected as a whole using HTTPS. The service is authenticated by the client using the service's SSL certificate. The client authentication is controlled through the ClientCredentialType.
https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.basichttpsecuritymode?view=netframework-4.8
I have a problem requesting HTTPS service over the internet on some client, when I try to do it the exception is thrown that "The ServicePointManager doesn't support proxies with the https scheme". On some clients my code works fine, but on some it fails with the exception. I think customers for whom the code works fine have http proxy, and https traffic comes through the http proxy, which is perfectly fine.
This function creates a new request:
var req = (HttpWebRequest)WebRequest.Create(url);
// This thing is needed to get default proxy
// and user credentials written in iexplore
var proxy = req.Proxy;
if(proxy != null) {
var puri = proxy.GetProxy(req.RequestUri);
var prox = new WebProxy(puri.ToString());
prox.Credentials = CredentialCache.DefaultCredentials;
req.UseDefaultCredentials = true;
req.Proxy = prox;
}
// Setting up custom cookies and UA
req.CookieContainer = Config.Cookies;
req.UserAgent = Config.UserAgent;
This is how I'm accepting all certificates:
ServicePointManager.ServerCertificateValidationCallback =
(sender, cert, chain, sslpolicy) => true;
It seems that ServicePointManager doesn't infact support working with proxies over https. How can I fix this issue? What if I somehow make the https WebRequest go through the http proxy instead of https, will this work, if so how can I do it?
Yes, you are right, It seems like The ServicePointManager does not support proxies of the https scheme.
If you change the scheme from HTTPS to HTTP it will work fine.
It's only an initial request between the client and proxy that is not secure or over SSL. The traffic tunneled through the proxy is encrypted or no depending on the server.
If you are trying to access any SSL server through the HTTP proxy, the traffic is still encrypted.
Let say if you are trying to access the HTTP server through HTTPS proxy still, the traffic is not encrypted.
Scenario: User talks with WebApi called 'Gateway' by angularjs client. 'Gateway' is like a facade or a proxy, so all requests from User to 'Gateway' will be forwarded to another WebApis.
Security details: 'Gateway' WebApi and all others WebApis are placed in IIS with HTTPS binding and SSL client certificate option is 'Accept'. So, user will provide valid client certificate to IIS and after verification, request will be handled by WebApi.
The problem: when 'Gateway' WebApi receives a request, client certificate is presented in Request object. Then I just forward this request using HttpClient to another WebApi. But when another WebApi endpoint receives a request, there is not client certificate attached any more.
Below is a code snipped of request forwarding:
var request = Request; // income request from angularjs
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(request.GetClientCertificate()); // setting up client certificate from user's request
using (var httpClient = new HttpClient(handler))
{
request.RequestUri = *chaning request address here*;
var response = await httpClient.SendAsync(request);
return ResponseMessage(response);
}
Note: If I try to go directly to the another WebApi, client certificate is presented as expected. If I try to go via 'Gateway', client certificate is presented as well in 'Gateway' request, but after it's successfully attached and request is sent, another WebApi does not receive any certificate attached.
Any ideas?
Thank you.
On your gateway server, you need to import an authentication key onto the "machine" certificate store (MMC.exe, add snap-in "Certificates", Computer account", Certficates-Personal-Certificates, import).
Grant permissions (for the auth cert) to the account which your IIS pool is using. (right-click the cert, All-Tasks, Manage private keys. Add, Advanced, Locations=[machine-name], find now, (probably) Network Service, Read).
In your web.config (on your gateway server), check your system.serviceModel / behaviors / endpointBehaviors / behavior / clientCredentials / clientCertificate. Make sure the attribute: storeLoction="LocalMachine", to use the cert from the machine key store.
I'm looking for the way to provide credentials (grammatically) for HTTP proxy that should be used to connect to service (Security Token Service), the proxy credentials differ from the credentials for the service.
I saw several posts here (it took me back to 2006-8) and the solution was by changing the default proxy
WebProxy proxy = new WebProxy("http://myproxyserver",true);
proxy.Credentials = new NetworkCredential("username", "password");
WebRequest.DefaultWebProxy = proxy;
I think it is risky to change the global setting for all WebRequests from my assembly that performs a dedicated task.
I'm wondering if in .NET 4.5 there is a better solution for this case.
Similar questions:
WCF Custom Http Proxy Authentication
How can I set an HTTP Proxy (WebProxy) on a WCF client-side Service proxy?
Don't set default proxy, set proxy object with desired credentials per request