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?
Related
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.
I'm approaching to WCF Service, starting with the tutorial provided by Microsoft. I created a very simple WCF Service (CalculatorService) and I've some doubts about the EndpointAddress of this service.
When I create the WCF Host, I set the Endpoint like this:
Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
// Step 2 Create a ServiceHost instance
ServiceHost selfHost = new ServiceHost(typeof(Service1), baseAddress);
// Step 3 Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "CalculatorService");
Everything works if I debug the entire solution, but, if I launch the WCFHost executing its .exe file, launching also the application of the Client gives me the following exception:
System.ServiceModel.EndpointNotFoundException: No endpoint listening in http://localhost:8732/Design_Time_Address/WcfServiceLibrary/Service1/.
The fact is that if I try to open a browser and search the address http://localhost:8000/GettingStarted/, I get correctly the page of the Service. I suppose that the Service is hosted at one address and the Client tries to access to it via a different one.
Could anyone help me to solve this issue?
If you have, in the client code, hard coded this address http://localhost:8732, then change it there. But your client is probably (you didn't put that info unfortunately in your question) automatically generated. In that case client config is in App.config file(if we are talking about your solution), and in config file of the .exe file when you build your project. You should look into your [ClientApplicationName].exe.config file and update the endpoint address to port 8000.
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")));
I've found myself in need of finding a WCF Binding that uses HTTPS/SOAP and must be duplex. I was programmatically using NetTcpBinding before but the binding now has to be HTTPS/SOAP. I did some research and it seems like it's not possible without creating your own CustomBinding.
However I'm sort of at a lost in what to do (not very familiar with bindings and the setup). I can't seem to get correct binding elements for what I need:
public class CustomHttpsBinding : CustomBinding
{
public CustomHttpsBinding()
{
}
public override BindingElementCollection CreateBindingElements()
{
ReliableSessionBindingElement https = new ReliableSessionBindingElement();
SecurityBindingElement security = SecurityBindingElement.CreateCertificateOverTransportBindingElement();
CompositeDuplexBindingElement duplex = new CompositeDuplexBindingElement();
SslStreamSecurityBindingElement ssl = new SslStreamSecurityBindingElement();
MessageEncodingBindingElement encoding = new GZipMessageEncodingBindingElement((MessageEncodingBindingElement) new BinaryMessageEncodingBindingElement());
HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
return new BindingElementCollection(new BindingElement[] { https, security, duplex, ssl, encoding, transport });
}
It gives me an invalid operation exception when checking soap over secure transport requirements saying my contract is configured with an authentication mode that requires integrity and confidentiality. However the transport cannot provide integrity and confidentiality.
Seems like my HttpsTransportBindingElement is not correct? I'm not sure.
Thanks
edit:
I did manage to get WSDualHttpBinding to work at one point, but it seems like HTTPS is not possible with it (as well as others on the internet which say it shouldn't even be used)
HTTP isn't duplex protocol - its request / response - that's why wsDualHttpBinding uses two connections - one in each direction. Silverlight achieves duplex over HTTP by polling for messages from the client under the covers
NetTcpBinding uses TCP which can quite happily be duplex
If you can wait until 4.5 is released later this year this has the NetHttpBinding which does duplex using the WebSocket protocol
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