I'm trying to build a C# SignalR app (console app on the server, winforms app on the client), and it works great (in Visual Studio) when both the client and server are on the same PC, but when I deploy the server and repoint the client to the server, I'm getting a "407 Proxy Authentication Required" exception when it tries to start.
This is my code...
var _connection = new HubConnection("http://www.redacted.com:8088/");
var _hub = _connection.CreateProxy("MyHub");
_connection.Start().ContinueWith(task =>
{
if (task.IsFaulted)
MessageBox.Show(string.Format("Could not connect - {0}", task.Exception.ToString()));
}).Wait();
I noticed that HubConnection has a Credentials property, and so I figured I'd try replacating some code I've used with WebServices when dealing with proxies (shown below, where I just make an HTTP request out and then pick up the proxy settings and credentials from that), but I get the same exception.
var _connection = new HubConnection("http://www.redacted.com:8088/");
var req = (HttpWebRequest)WebRequest.Create("http://www.google.com");
var proxy = new WebProxy(req.Proxy.GetProxy(req.RequestUri).AbsoluteUri) {UseDefaultCredentials = true};
_connection.Credentials = proxy.Credentials;
var _hub = _connection.CreateProxy("MyHub");
_connection.Start().ContinueWith(task =>
{
if (task.IsFaulted)
MessageBox.Show(string.Format("Could not connect - {0}", task.Exception.ToString()));
}).Wait();
This is required for some work I'm doing for a client where they want their local PCs to be able to receive messages from a remote system that's hosted outside the company.
Thanks!
Try to set the DefaultWebProxy:
WebProxy wproxy = new WebProxy("new proxy",true);
wproxy.Credentials = new NetworkCredential("user", "pass");
WebRequest.DefaultWebProxy = wproxy;
Related
public async Task<string> echo()
{
using var httpClientHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
// The port number must match the port of the gRPC server.
using var httpClient = new HttpClient(httpClientHandler);
using var channel = GrpcChannel.ForAddress("http://10.0.50.120:30000", new GrpcChannelOptions { HttpClient = httpClient });
var client = new StorageService.StorageServiceClient(channel);
var reply = await client.echoAsync(new EchoRequest { });
return reply.ServiceName;
}
I made a client with blazer and I want to communicate with other servers through echo. However, an exception has occurred.
"The connection failed because the target computer refused to connect. " I thought it was not possible because of the authentication of entering the ID and password of the server. I want to know if that's the right problem and if it is, I want to know how to enter it with code.
my client is behind a corporate proxy on http://localhost:9000/. I've tried to set the Proxy in my .Net Core 5 WebApi App via that code:
var client = new CosmosClient(dbConfig.GetValue<string>("Endpoint"), dbConfig.GetValue<string>("Key"), new CosmosClientOptions()
{
WebProxy = new WebProxy("http://localhost:9000/", true)
});
But the connection is not Working. I receive a Service unavailable. After closing proxy connection and having direct internet access my .Net backend is working. Any idea?
Looks like the answer is Gateway-mode:
var client = new CosmosClient(dbConfig.GetValue<string>("Endpoint"), dbConfig.GetValue<string>("Key"), new CosmosClientOptions()
{
WebProxy = new WebProxy("http://localhost:9000/", true),
ConnectionMode = ConnectionMode.Gateway
});
I use FiddlerCore to capture HTTP traffic when performing web UI tests with Selenium (C#) ChromeDriver. I have finally managed to get it working by trial and error, but need a hint on why my solution works and the logical way (for me) doesn't.
I configure the fiddler proxy as:
CONFIG.IgnoreServerCertErrors = false;
FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true);
var startupSettings =
new FiddlerCoreStartupSettingsBuilder()
.ListenOnPort(0)
.DecryptSSL()
.OptimizeThreadPool()
.Build();
FiddlerApplication.Startup(startupSettings);
HttpPort = FiddlerApplication.oProxy.ListenPort;
FiddlerApplication.Log.LogFormat("Created HTTP endpoint listening on port {0}", HttpPort);
secureEndpoint = FiddlerApplication.CreateProxyEndpoint(HttpsPort, true, Host);
if (secureEndpoint != null)
{
HttpsPort = secureEndpoint.ListenPort;
FiddlerApplication.Log.LogFormat("Created secure endpoint listening on port {0}, using a HTTPS certificate for '{1}'",HttpsPort, Host);
}
CertMaker.trustRootCert();
This basically follows the demo project provided for FiddlerCore. Note, that the proxy is not registered as system proxy.
Then, ChromeDriver is configured as:
var chromeDriverService = ChromeDriverService.CreateDefaultService();
chromeDriverService.HideCommandPromptWindow = true;
var options = new ChromeOptions();
options.Proxy = new Proxy()
{
HttpProxy = $"{SkicoProxy.Host}:{SkicoProxy.HttpPort}",
SslProxy = $"{SkicoProxy.Host}:{SkicoProxy.HttpPort}"
};
_driver = new ChromeDriver(chromeDriverService, options);
What doesn't work, although I would expect it to is:
options.Proxy = new Proxy()
{
HttpProxy = $"{SkicoProxy.Host}:{SkicoProxy.HttpPort}",
SslProxy = $"{SkicoProxy.Host}:{SkicoProxy.HttpsPort}" // HTTPS PORT INSTEAD HTTP PORT
};
Still, if I do not configure the endpoint in Fiddler, SSL websites are shown as unsafe in Chrome.
Why doesn't SSL traffic needs to be routed through the according endpoint and why does it even work if it is not proxied through the secure endpoint?
I have a .NET Core 2.0 application and need to call a WCF client from one of its controllers, and pass the user credentials for authentication.
Within the .net core app I created a reference for the WCF client using the Connected Services (WCF Web Service Reference Provider) and now in a process of configuring the call. Note that I can use the same endpoint form a 4.6 framework application without any problems.
Here's my code:
var binding = new BasicHttpBinding {Security = {Mode = BasicHttpSecurityMode.Transport}};
var address = new EndpointAddress("https://my-endpoint.asmx");
var client = new MyAppSoapClient(binding, address);
var credentials = CredentialCache.DefaultNetworkCredentials;
client.ClientCredentials.Windows.ClientCredential = credentials;
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
var response = client.GetStuff("param").Result;
I face a number of problems:
It has to be a https call
I need to pass the currently log in user credentials to the call
The current error I get is as follows:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate, NTLM'
Also the ConnectedService.json (created automativcally by WCF Web Service Reference Provider) has a predefined endpoint Uri.. I don't understand why I need to pass the address to the client manually (the code seems to be forcing me to do so).. ideally I'd like to get this dynamically amended in json depending on environment.
Thanks.
I noticed that you passed the current logged-in user as a Windows credential (which is also necessary for enabling impersonation), but you did not explicitly set the client credentials for the transport layer security.
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
Also the ConnectedService.json (created automativcally by WCF Web
Service Reference Provider) has a predefined endpoint Uri.. I don't
understand why I need to pass the address to the client manually (the
code seems to be forcing me to do so)
You can modify the method of automatic generation of proxy client to construct client proxy class (located in the reference.cs)
Modify the binding security
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WebService1Soap))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
result.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
return result;
}
Modify the endpoint.
private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WebService1Soap))
{
return new System.ServiceModel.EndpointAddress("http://10.157.13.69:8001/webservice1.asmx");
Construct the client proxy class.
ServiceReference1.WebService1SoapClient client = new WebService1SoapClient(WebService1SoapClient.EndpointConfiguration.WebService1Soap);
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
client.ClientCredentials.Windows.ClientCredential.Password = "123456";
Feel free to let me know if there is anything I can help with.
My binding was missing the security Ntlm credential type (see below).
Problem solved.
var binding = new BasicHttpBinding {Security = {Mode = BasicHttpSecurityMode.Transport,
Transport = new HttpTransportSecurity(){ClientCredentialType = HttpClientCredentialType.Ntlm } }};
I need to develop a WCF Hosted in a console app WebService.
I made it work using the Mutual Certificate (service and client) method using SecurityMode.Message.
But now i need to change the Security Mode to SecurityMode.Transport and use the wsHttpBinding with SSL. I made this code to host the service but i cannot get the wsdl with the browser, or execute some webmethod in the console app client.
static void Main()
{
var httpsUri = new Uri("https://localhost:8089/HelloServer");
var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var host = new ServiceHost(typeof(WcfFederationServer.HelloWorld), httpsUri);
host.AddServiceEndpoint(typeof(WcfFederationServer.IHelloWorld), binding, "", httpsUri);
var mex = new ServiceMetadataBehavior();
mex.HttpsGetEnabled = true;
host.Description.Behaviors.Add(mex);
// Open the service.
host.Open();
Console.WriteLine("Listening on {0}...", httpsUri);
Console.ReadLine();
// Close the service.
host.Close();
}
The service is up, but i cannot get nothing on the https://localhost:8089/HelloServer.
On fiddler the get request via browser shows me this message:
fiddler.network.https> HTTPS handshake to localhost failed. System.IO.IOException
What im missing here?
Thanks
EDIT:
The Console Application Client Code
static void Main()
{
try
{
var client = new HelloWorldHttps.HelloWorldClient();
client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.TrustedPeople,
X509FindType.FindBySubjectName,
"www.client.com");
Console.WriteLine(client.GetData());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
Getting this error:
Could not establish trust relationship for the SSL/TLS secure channel
When it comes to the service, you need to map the certificate to the specific port as described here
http://msdn.microsoft.com/en-us/library/ms733791(v=vs.110).aspx
As for the client, you need to skip the verification of certificate properties like valid date, the domain by relaxing the certificate acceptance policy. An easiest way would be to accept any certiticate
ServicePointManager.ServerCertificateValidationCallback = (a,b,c,d) => true
You can finetune the acceptance callback according to the docs to best fit your needs.