Unable to use NettcpBinding from another computer in my local network - wcf

I built a WCF Service in one of my machines of my local network, it has both http and net.tcp (htpp,net.tcp) as enabled protocols in IIS manager.
From another machine a build a client app, and define the endpoints automatically using the Add Service Reference... dialog, I type the service address and when it appears I set the name and click OK. The App.config is updated with two endpoints, one for http (BasicHttpBinding) and the other for net.tcp (NetTcpBinding) as expected.
When running the client app, if I use the BasicHttpBinding:
"using (var proxy = new ProductsServiceClient("BasicHttpBinding_IProductsService"))"
it runs OK, and shows the expected data.
But when I use the NetTcpBinding:
"using (var proxy = new ProductsServiceClient("NetTcpBinding_IProductsService"))"
It throws a SecurityNegotiationException saying that:
"A remote side security requirement was not fulfilled during authentication. Try increasing the ProtectionLevel and/or ImpersonationLevel."
If I do it all in the same machine, I donĀ“t get any exception.
What should I do?
Rafael

By default, the BasicHttpBinding supports no security. So when calling the service from another computer, it will work also.
But by default, NetTcpBinding requires a secure channel. And the default security mode is Transport, so when calling the service from another computer, it will throw a security exception.
The most easy way to solve it is to set the security mode to None as following:
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfiguration" >
<security mode="None" />
</binding>
</netTcpBinding>
Then we use it in the endpoint
<endpoint address="net.tcp://nelson-laptop:8080/Whatever"
binding="netTcpBinding"
bindingConfiguration="netTcpBindingConfiguration"
contract="ProductsService.IProductsService"
name="NetTcpBinding_IProductsService" />

In Your question you are using the default net.tcp port 808 but have opened port 80 in the firewall. If it is not a typo in the question it could be why it fails.

Related

scalable WCF solution

I am trying to implement scalable wcf solution found at NetFX Harmonics: Creating Streamlined, Simplified, yet Scalable WCF Connectivity
So my solution have 4 projects
Contact.Service (Service and Data Contracts)
Contact.ServiceImpl (HostFactory and Service itself)
Contact.ServiceHost (Web.config and Person.svc)
Contact.ServiceClient
Contact.ServiceClient have App.config and Program.cs which actually call service.
App.config
<configuration>
<appSettings>
<add key="PersonServiceActiveEndpoint" value="PersonServiceBasicHttpBinding" />
</appSettings>
<system.serviceModel>
<client>
<endpoint name="PersonServiceBasicHttpBinding"
address="http://localhost:1031/Person.svc"
binding="basicHttpBinding"
contract="Contact.Service.IPersonService" />
</client>
</system.serviceModel>
</configuration>
Program.cs
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:1031/Person.svc");
IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();
Person person = personService.GetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6");
Console.WriteLine(person.FirstName);
When I try running this example exception is thrown:
There was no endpoint listening at http://localhost:1031/Person.svc that could accept the message. This is often caused by an incorrect address or SOAP action.
P.S. Person.svc is in my Contact.ServiceHost project
<%# ServiceHost Service="Contact.Service.PersonService" %>
what is the config of the service host? sounds like one of 2 problems:
the service host is not set up to listen on the same port.
the host application is not being run at all
I imagine that by checking the web.config of the service host project you'll likely find that it is either listening on a different port, or not being run at all, and hence not listening.
Is the Visual studio host starting up and hosting the service? You usually get a little 'toast' pop up window in the notification area next to the clock saying the the host is running and you can see which port it is running on. if this is not happening then it is likely that you need to configure it to start the host project as well as the client.
To enable both the client and server to start at the same time you need to:
Right-click on your solution file, and choose Set Startup Projects...
Choose Multiple startup projects and choose Start for your client and server project, leave the other ones set to none.

WCF SOAP over HTTPS, WCF Test Client calls the http address and the server responds with 404

TL;DR version is at the bottom.
I have constructed three WCF web services -- one that's using .NET 4 and two that's using .NET 3.5 -- that is consumed by an Android client. The Android client performs the calls using ksoap2-android. When the services were complete and the client could make all the calls and get all the data from the services, we decided to activate HTTPS communication for the web services. They are hosted on a server running IIS.
I'm not alone on this task. I work full-time with it, mainly the Android client. I have two coworkers, both of which have a lot of other responsibilities. The first is mostly involved in the services and the second is mostly involved in the server.
I've read a lot of guides, blogs and articles on the Internet on how to enable HTTPS for a WCF web service, but still I haven't been able to completely resolve this. For the Android client to be able to consume the client, we are limited to using the basicHttpBinding, since the wsHttpBinding contains some security details that are not supported by Android, or something. I'm not sure, but I read it some forum somewhere. If I'm wrong, I'd happily be corrected!
Okay, so I'll give a short account of what I've done so far:
I've enabled transport security, this is how the binding(s) looks:
<bindings>
<basicHttpBinding>
<binding name="basicHttp" closeTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
I've enabled meta data publishing over HTTPS using this line of code:
<serviceMetadata httpsGetEnabled="true" />
and this:
<endpoint address="" binding="mexHttpsBinding" contract="IMetadataExchange" />
Also, my second coworker has installed a trusted certificate (a real certificate from a CA) on the IIS server and added a https binding on the server.
Okay, so far, so good. Now we could connect to the services in the browser.
When we had done this it was possible to visit the service in the browser in a secure, encrypted, manner.
The problem is that it isn't possible to make a call to the service, neither in Android nor WCF Test Client. If I call the service on the https address, I get a 404 in response. WCF Test Client returns this:
There was no endpoint listening at https://[my service address] that could accept the message. This is often caused by an incorrect address or SOAP action.
To be able to debug this, I'm using Wireshark to intercept the messages and see what really happens. I've found out that after the set up procedures (handshake, establishing trust etc.) the client sends the header and get a 101 Continue in response, after which it POSTs the body. This should be normal behavior. But then the service returns 404 Not Found. Wireshark says that the full request URI is the http address. I've configured the server to use the https address, so why does it make a call to the http address?
I've tried setting the address and listenUri attribute of the endpoint to https and http respectively and the other way around. If I do that, the server answers the request with 405 Method Not Allowed.
Is there any way to solve this? What am I missing?
What am I missing?
TL;DR version below
I'm hosting three WCF SOAP web services with IIS, one using .NET 4 and the others using .NET 3.5. I'm trying to make a call from the WCF Test Client over HTTPS. I've enabled transport security, meta data publishing over HTTPS, installed a trusted certificate and added a https binding on the server.
When I try to make a call from WCF Test Client it says that there was no endpoint listening at the address. Wireshark tells me it makes the call to the http version of the service (i.e. "http://[my address]" instead of "https://[my address]"), although it is configured to call the https address. The service returns 404 Not Found. If I set the address of the service to https and listenUri to http, I get 405 Method Not Allowed. If I do it the other way around it says that it cannot be activated. What am I missing?
I solved this by removing the endpoint and using the <protocolMapping> tag, like this:
<protocolMapping>
<add scheme="https" binding="basicHttpBinding" bindingConfiguration="basicHttps" />
</protocolMapping>

Biztalk gets MessageSecurityException with WCF-WsHTTP endpoint

When Biztalk 2009 calls a regular ASP.NET webservice via an WS BasicHTTP adapter, it gets a System.ServiceModel.Security.MessageSecurityException: the HTTP request is unauthorized with client authentication scheme "Anonymous". The authentication header received from the server was : Negotiate NTLM".
The webservice is hosted in IIS (7.5), with anonymous access disabled, and Windows Authentication enabled.
Your send port needs to be configured to use NTLM security, as that appears to be what the web service requires.
Open the send port's configuration, open the transport type's (WCF-BasicHttp) configuration, and go to the Security tab. There, set the security mode to Transport. That will allow you to set the Transport client credential type to Ntlm.
This will cause BizTalk to authenticate to the web service using NTLM. It will use the account of the BizTalk host in which your send port is running. If that account does not have access to the web service, then you'll either need to grant it access or look at alternatives, such as switching from NTLM to Basic (which allows you to specify the credentials under that same Security tab). A discussion about this issue is here.
Of course, you did mention that you configured the web service for Windows Authentication, so you can also try setting the Transport client credential type to Windows. That should still use the BizTalk host process's account, though, just like NTLM.
FWIW here's a paste of a WCF basicHttpBinding exposed to BizTalk 2009
<services>
<service ... >
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="binding4BizTalk"
bindingNamespace="xxx"
... >
<!-- Delete the identity tag here -->
</endpoint>
And then under the bindings
<bindings>
<basicHttpBinding>
<binding name="binding4BizTalk" ...>
<security mode="None" />
Hope is of some use?

WsHttpBinding with security mode TransportWithMessageCredential in IIS 7 not working

We are currently migrating a WCF service from IIS 6 to IIS 7. The service contains some non-SSL endpoints for internal streaming purposes and some exposed endpoints secured with SSL.
The public, secure endpoints are implemented using wsHttpBinding and security mode="TransportWithMessageCredential". The binding reads as follows:
<wsHttpBinding>
<binding name="CustomSecurityBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
The credentials are authenticated against a custom user repository for validation.
After deploying the service to IIS 7 (64bit Win2k8), all services (basicHttpBindings) respond correctly, expect for the wsHttpBindings. If triggered using https, we always get a HTTP 400 status code (Bad Request).
After enabling tracing in IIS, we could kinda narrow down the problem, although the message from the trace did not really help:
MODULE_SET_RESPONSE_ERROR_STATUS Warning
ModuleName="ManagedPipelineHandler", Notification="EXECUTE_REQUEST_HANDLER",
HttpStatus="400", HttpReason="Bad Request", HttpSubStatus="0", ErrorCode="Der
Vorgang wurde erfolgreich beendet. (0x0)", ConfigExceptionInfo=""
Steps done so far:
re-installed WCF extensions in IIS 7 (ServiceModelReg.exe -r -y)
enabled https protocol for host, added self-signed certificate to host
played around with dns/identity setting in wcf configuration
added a base address to wcf service config
After 2 hours of googling and trying to make this work, i ask you as a last resort of hope: Does anybody know this strange behaviour of IIS 7?
Have you verified that the SSL binding is configured in applicationHost.config (%windir%\system32\inetsrv\config\schema\IIS_Schema.xml) and that the HTTP.sys store contains a valid certificate has and store name for the binding? Secondly, the true error could be masked by the 400 error, have you tried altering your wsHttpBinding in configuration to increase the maxBufferPoolSize and maxReceivedMessageSize to some extremely high values and see if this continues?

Can IIS-hosted WCF service be configured for BOTH Windows Auth and Anonymous?

I've got a small WCF webservice working with the built-in WCF Service Host and with hosting by the Visual Studio 2008 built-in development webserver.
I these hosting enviroments I have relied on the WCF Test Client for invoking the service methods.
Now I am running into problems with my next phase of testing:
I have it hosted in IIS 5.1 on my WinXP dev machine and I think maybe the problem is I cannot continue to use WCF Test Client anymore. Here is what's happening:
Case 1: "Anonymous Access" is CHECKED (ENABLED)
WCF Test Client UI comes up properly, exposing the WebMethods and the INVOKE button.
Yet when I click INVOKE it fails to connect with a backend data store (a 3rd party product) that requires Windows authentication. I could post the error I get back from the product.DLL but I don't think it is relevant.
Case 2: "Anonymous Access" is un-CHECKED (DISABLED)
WCF Test Client UI fails to even initialize properly. My researching of this tells me that MEX (WS-Metadata Exchange) requires "Anonymous Access" and (apparently) WCF Test Client requires MEX. Here are key snippets of the error being returned:
Error: Cannot obtain Metadata from http://localhost/wcfiishost
The remote server returned an error: (401) Unauthorized.HTTP GET Error
URI: http://localhost/wcfiishost
There was an error downloading 'http://localhost/wcfiishost'.
The request failed with the error message:
Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service
The are lots of explanations of binding options, message security, etc. and stuff I honestly do not understand. Here is my take on where I am but I would love your opinions:
(a) Because I know my WCF webservice MUST be configured to use Windows Authentication, I conclude I cannot continue to use the WCF Test Client when hosting my service in IIS. That it has effectively outlived it's usefulness to me. I will just have to take the time to write a web client because WCFTestClient won't work without Anonymous.
(or)
(b) It is possible to use WCF Test Client if it and the hosted service are configured propertly (I just don't know what the special configuration techniques are for this).
Which is correct? Time to stop using WCFTestClient or is there a way to have it both ways? Thanks in advance for your advice.
EDIT: 11 June 09
Is there anything else I can provide to help someone else help me on this question?
I just tried to have the same setup - but in my case, everything seems to work just fine.
ASP.NET web site
WCF service, using basicHttpBinding without any special settings at all
IIS Application with anonymous = enabled and Windows authentication = enabled (both turned on)
I can easily connect to it with the WcfTestClient and retrieve the metadata, and I can then call it, no problem.
Inside my service function, I check to see whether the current user is a known user or not, it is correctly identified as a Windows authenticated user:
ServiceSecurityContext ssc = ServiceSecurityContext.Current;
if (ssc.IsAnonymous)
{
return "anonymous user";
}
else
{
if(ssc.WindowsIdentity != null)
{
return ssc.WindowsIdentity.Name;
}
if (ssc.PrimaryIdentity != null)
{
return ssc.PrimaryIdentity.Name;
}
}
return "(no known user)";
I don't really know, what more to check for (except I'm on Vista with IIS7). Any chance you could include this code to check for the user in your service code? Just to see....
Marc
Marc, your setup is not even close to Johns.
John uses WSHttpBinding that uses Windows Credentials for Message mode transport. The Windows Authentication isn't being used with BasicHttpBinding. Furthermore, John had AnonymousAuthentication disabled, which is why the Metadata Exchange (mex) is failing.
The call won't even reach inside the service side function, because we get a Error 401 (Unauthorized) when we try to call.
Just know John, I have the same issue, and I'm trying to somehow set up separate bindings per endpoint. Hopefully that will work.
When I set the title/subject of this question and reached a dead end here, I opened up the same issue in the MSDN forum with a different emphasis on the title (content of question essentially the same).
For me, the real issue was how to use WCFTestClient in IIS without Anonymous Authentication being set (because my service needed Integrated Windows Authentication only).
Mex apparently requires Anonymous and by default WCFTestClient seems to need Mex. The key seems to be accomodating both my doctoring up the web.config file carefully.
Anyway, I got it working with this web.config below (the MSDN link is here:
<?xml version="1.0"?>
<configuration>
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="wsBindingConfig"
contract="sdkTrimFileServiceWCF.IFileService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="basic"
binding="basicHttpBinding"
bindingConfiguration="bindingConfig"
contract="sdkTrimFileServiceWCF.IFileService" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="bindingConfig">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="wsBindingConfig">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</serviceBehaviors>
</behaviors>