Consuming a wcf service over the internet - c#

I have a wcf service that uses the WsHttpBinding as a binding.
This service is hosted on a server that has a public IP.
I need to consume this wcf service over the internet, but it is giving me the below error.
here was no endpoint listening at http://IP:9962/MyService that could accept the message.
Any Help is very appreciated.

It's a non-standard HTTP port, so my first question would be - firewall / routing issues?

I found the answer.
1- I need to add security on the binding that i am using.
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
2- I need to add custom authentication on the service host.
svh.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
People365UserNameValidator cs = new People365UserNameValidator();
svh.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = cs;
svh.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
StoreName.TrustedPeople, X509FindType.FindByIssuerName, "Certificate Name");
3- i need to add a certificate in the mmc of the computer

Related

Set ServiceBehavior on channelfactory WCF Net.Pipe

I am hosting a Net.Pipe WCF service from a forms application, which runs on a server for mostly internal calculations. To improve on this I was tasked with creating a Rest shell around this service so it becomes reachable from outside of the server. I managed to connect to this service with ease, but as soon as I drop it on the live server My rest shell can no longer connect, I tried debugging this, but the main error message that gets logged is:
The server was unable to process the request due to an internal
error. For more information about the error, either turn on
IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute
or from the serviceDebug configuration behavior) on the server in
order to send the exception information back to the client, or turn on
tracing as per the Microsoft .NET Framework SDK documentation and
inspect the server trace logs.
Thing is that I connect to this service from code and I cannot figure out how to either convert the way I connect to a service host so I can add the Service behavior or add the behavior to my channel factory.
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
ServiceDebugBehavior behavior = new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true };
EndpointAddress ep = new EndpointAddress("net.pipe://localhost/IPCService");
ChannelFactoryfactory = new ChannelFactory<RadanWrapper.IRadanContract>(binding);
// This line doesn't work
factory.Endpoint.EndpointBehaviors.Add(behavior as IServiceBehavior);
_channel = factory.CreateChannel(ep);
So the question is either: How do I connect the behavior to the channel factory, or alternatively, how can I connect to this net.pipe service through service host. (I am still looking into the second options)
I found the problem, I tried adding the behavior to the rest shell (connecting end), while it should have been added to the forms application (Hosting end) that was hosting the net.Pipe WCF
ServiceHost serviceHost = new ServiceHost(typeof(IPCService));
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
// Create new behavior, remove any existing behaviors and add this new one.
var behavior = new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true };
serviceHost.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
serviceHost.Description.Behaviors.Add(behavior);
serviceHost.AddServiceEndpoint(typeof(IPCService), binding, "net.pipe://localhost/IPCService");
serviceHost.Open();
Good thing I now got an actually working error message, turns out I was missing a specific dll that didn't get build correctly during deployment to the server.

Add Header to WCF RequestSecurityToken Message

I'm attempting to set up a client (Web Application) and service (WCF Service) that will communicate using a WSHttpBinding. It appears that in order to use this binding the client sends preliminary messages to set up the channel.
Between the client and the service exists a service bus which is routing on a custom header. The message, when using BasicHttpBinding security, routes without issue.
My question is: Is there any way to add the same custom header to the preliminary RequestSecurityToken message?
Thank you in advance.
This has been resolved.
Unfortunately, according to the MSDN documentation, a service using WCF transport security cannot go through a router, nor should either, service nor client, be located on the internet (https://msdn.microsoft.com/en-us/library/ff648863.aspx#TransportSecurity).
We wanted to violate both 'principles'.
So in order to cut down the messages, from five calls and responses to one, we switched to Message Security and turned off EstablishSecurityContext and NegotiateServiceCredential. - This had to be done on both the Service and Client configuration settings.
In addition to this, a noteworthy tip may be that, in order to point the service to our service bus, we changed theClientViaBehavior of the service on the Client Side.
Turn off EstablishContext and NegotiateServiceCredential:
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.NegotiateServiceCredential = false;
Point client to Service Bus:
serviceClient.Endpoint.EndpointBehaviors.Add(new ClientViaBehavior(new Uri("http://url/WCFService/ServiceName.svc")));

Using an IP address for a WCF Service

I have a C# app that calls my WCF on my server.
At some time I will want to move part of my uploading process from client to server to a different server.
So, this is what I was going to do.
My desktop application invokes a WCF hosted on my server using the full DNS name ~ www.mysite.com.
That [web method] will then return an IP address to the client.
The client will then upload images to a DIFFERENT server that is accessible only by an IP address.
The idea is that if my app is successful and I would need to 'load-balance' the image uploads I would then have a mechanism to specify different destination servers to my clients.
So, I started looking in StackOverFlow for a way to dynamically set the IP address/End-Point of my WCF. This was easy to do for web services but it seems to me a bit more difficult for WCF.
Needless to say I was about to go through the answers here but came across a comment saying that the WCF needs to be using DNS.
Is this true?
As this is the only server I got and it is using DNS (I have not got access to a secondary server yet) I cannot test this out.
Are both things possible?
When you write a web service client, you can change the server endpoint programmatically. It has nothing to do with using WCF or not in the server.
MyClient client = new MyService.MyClient();
client.Endpoint.Address = new EndpointAddress(new Uri("target URL"));
client.Open();
You could find more details on the EndPointAddress MSDN reference.
Hope I helped!
MyClient client = new MyService.MyClient();
client.Endpoint.Address = new EndpointAddress(new Uri("target URL"));
client.Open();
It works, we could also use
myService.MyClient client = new myService.MyClient ();
//enter code here, when the service is created as wcf application

WCF service message security

I have a problem with message security in WCF. I'm using this tutorial: http://www.codeproject.com/Articles/96028/WCF-Service-with-custom-username-password-authenti
I have 2 services. First one, with wshttpbindig is OK. Second one, with wsdualhttpbinding doesn't work. I have an exception when I'm opening proxy after setting Credentials. It looks like I have to set Credentials before I open proxy, but I can't open proxy after set Credentials. I was using only one certificate for both services.
What I should do with this?
When I have 2 services do I have to use 2 certificates? If yes how can I do it?
InstanceContext context = new InstanceContext(this);
proxy = new CommunicationServiceReference.CommunicationServiceClient(context);
_proxy.ClientCredentials.UserName.UserName = UserSession.Login;
_proxy.ClientCredentials.UserName.Password = UserSession.Password;
_proxy.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
_proxy.Endpoint.Address.Uri.Port.ToString();
_proxy.Open();
EDIT:
Is it possible to configure service with wsdualhttpbinding using tutorial i posted above?

Error when setting WCF NetTcpBinding to only accept local connections

I am trying to set up a WCF service which only accepts incoming messages/connection from itself.
I have been able to successfully create the service and run it and communicate with it using this code to create the WCF Endpoint (not restricted to localhost only)
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
_host = new ServiceHost(this, new Uri("net.tcp://localhost:19852"));
_host.Description.Behaviors.Add(new ServiceMetadataBehavior());
_host.AddServiceEndpoint(typeof(ISyncClient), binding, "SyncService");
_host.AddServiceEndpoint(typeof(IMetadataExchange), System.ServiceModel.Description.MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
_host.Open();
As soon as I add this line to restrict to connections from localhost
binding.HostNameComparisonMode = HostNameComparisonMode.Exact;
I get this exception
System.ServiceModel.AddressAlreadyInUseException: There is already a listener on IP endpoint 0.0.0.0:19852. This could happen if there is another application already listening on this endpoint or if you have multiple service endpoints in your service host with the same IP endpoint but with incompatible binding configurations. ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
I'm not even sure what I am doing is the correct way to restrict WCF access, but obviously its not working. To me this looks like some sort of conflict with the MEX endpoint. As far as I know I NEED the mex endpoint so I can't get rid of it. Anyone point me in the direction of a solution?
The easy way to do this is with a named pipe binding. It only supports local calls. From Choosing a Transport:
When communication is required between different WCF applications on a
single computer, and you want to prevent any communication from
another machine, then use the named pipes transport.
Also, Mex points are completely optional. You can get rid of its endpoint and behavior without a problem.

Categories

Resources