WCF: Using nettcp in an Silverlight 4.0 application with HTTPS - wcf

I have a Silverlight 4.0 application using nettcp working in HTTP. I then attempted to switch from http to https. This is where I started to run into issues. When I run the application I receive an Internet Explorer notification "Display Mixed Content?". If I click "Yes" then I receive an error in my application:
Could not connect to net.tcp://ServerName:4502/TestService.svc/netTcp. The connection attempt lasted for a time span of 00:00:01.2191219. TCP error code 10013: An attempt was made to access a socket in a way forbidden by its access permissions.. This could be due to attempting to access a service in a cross-domain way while the service is not configured for cross-domain access. You may need to contact the owner of the service to expose a sockets cross-domain policy over HTTP and host the service in the allowed sockets port range 4502-4534.
My ClientConfig is as follows:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NetTcpBinding_ITestService">
<binaryMessageEncoding />
<tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="net.tcp://ServerName:4502/TestService.svc/netTcp"
binding="customBinding" bindingConfiguration="NetTcpBinding_ITestService"
contract="TestServer.ITestService" name="NetTcpBinding_ITestService"/>
</client>
</system.serviceModel>
</configuration>
My Web.config is as follows:
<netTcpBinding>
<binding name="netTcpBindingConfig">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="TestService">
<endpoint address="netTcp" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig" contract="ITestService" />
<endpoint address="mex" binding="mexHttpsBinding" name="mex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://ServerName:4502/TestService.svc" />
<add baseAddress="https://ServerName/TestService.svc" />
</baseAddresses>
</host>
</service>
</services>
At the Root of my server I have a file called clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="http://*"/>
<domain uri="https://*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
<socket-resource port="4502-4530" protocol="tcp" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
The nettcp communication does not need to be secure, but other services in the application require security. Is it possible to get nettcp running in an HTTPS hosted application?

Related

WCF Rest service does not work over HTTP in IIS 8

My team has a small WCF Rest service written in .NET 4.0. Historically, it has been deployed on Server 2008 machines running IIS 7, using the following binding configuration:
<bindings>
<webHttpBinding>
<binding name="httpsBinding">
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
As one would expect, the service works just fine with HTTP or HTTPS, so long as the web server is configured with bindings for each.
However, when we install the service on a Server 2012 box running IIS 8, the service will work just fine via HTTPS, but requests over HTTP fail with a 404 status.
We have looked at the IIS configuration of the Server 2008 and Server 2012 machines, but there is nothing that stands out as an obvious culprit. All the settings appear to be the same.
Is there any extra configuration that needs to be done either in IIS or in the web config? There are plenty of questions out there on SO and MSDN about services which work with HTTP and not HTTPS, but none that I have seen for the reverse.
edit:
According to the WCF trace logs, the 2008 machine opens endpoint listeners on both HTTP and HTTPS, whereas the 2012 machine only opens an endpoint listener for HTTPS.
To be sure I am not missing anything on the service itself, I have installed the same MSI on both machines and even over-wrote the web.config on the 2012 box with the one from the 2008 box (though they should have been identical anyways). There is no change in behavior.
edit 2:
Below is the web.config in its entirety:
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="None"/>
<compilation targetFramework="4.0"/>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="service1">
<endpoint behaviorConfiguration="webHttp" binding="webHttpBinding" bindingConfiguration="httpsBinding" contract="service1"/>
</service>
<service name="service2">
<endpoint behaviorConfiguration="webHttp" binding="webHttpBinding" bindingConfiguration="httpsBinding" contract="service2"/>
</service>
<service name="service3">
<endpoint behaviorConfiguration="webHttp" binding="webHttpBinding" bindingConfiguration="httpsBinding" contract="service3"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="httpsBinding">
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Add an HTTP endpoint for each service like this:
<endpoint behaviorConfiguration="webHttp" binding="webHttpBinding" bindingConfiguration="httpBinding" contract="service3"/>
And associated binding for HTTP only:
<binding name="httpBinding">
<security mode="None"/>
</binding>

WCF SSL endpoint address is not HTTPS

Im trying to host my SSL WCF service locally on my PC (IIS 7) and for some reason i cant connect to it. What i need is to use SSL and send in credntials to authenticate the user before calling some function.
When i connect to it, i get There was no endpoint listening at https://[computer name]/YYY.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
the inner message is The remote server returned an error: (404) Not Found.
What i have noticed is that when i access the WSDL (hosted over https) the endpoint address is not http*S* and i think that is why my service is probably failing.
here is part of my WSDL
<wsdl:service name="WSNAME">
<wsdl:port name="WSHttpBinding_INams" binding="tns:WSHttpBinding_INams">
<soap12:address location="http://[computer name]/YYY.svc" />
<wsa10:EndpointReference>
<wsa10:Address>http://[computer name]/YYY.svc</wsa10:Address>
<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<Spn>host/[computername]</Spn>
</Identity>
</wsa10:EndpointReference>
This is my service config file
<service behaviorConfiguration="test" name="NewServiceType">
<endpoint address="https://[computer name]/YYY.svc" binding="wsHttpBinding"
bindingConfiguration="WsBinding" name="WS" contract="Authentication2.INams" />
<endpoint address="mex" binding="mexHttpBinding" name="MX" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://[computer name]/XXX.svc" />
</baseAddresses>
</host>
can anyone point out what am i doing wrong?
my web.config
<system.serviceModel>
<protocolMapping>
<remove scheme="http" />
<add scheme="http" binding="wsHttpBinding" />
</protocolMapping>
<bindings>
<wsHttpBinding>
<binding name="wsbinding">
<security mode="TransportWithMessageCredential">
<transport proxyCredentialType="Basic" />
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="NewServiceType">
<endpoint address="/WS" binding="wsHttpBinding"
bindingConfiguration="wsbinding" name="WS" contract="Authentication3.IService1" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
name="MX" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"
httpsGetUrl="https://[computerName]/Service1.svc" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
FOUND IT !!
WCF service returns 404 over https but not http
the problem is that my service element name was what the editor adds by default "MyNewService" or whatever the default name is. You HAVE to use the fully qualified name..
<services>
<service name="[Namespace].[service class name]">
This cost me over 2 long days of constant work and research. If this works for you, please vote that guys answer up - NO ONE has ever mentioned this point .. i couldnt because im still new
Your endpoint has a bindingConfiguration attribute defined of WsBinding. There should be a section of the web.config that defines this configuration, including the security mode to be used (presumably transport or transportWithMessageCredential if you want to use SSL).
For example:
<bindings>
<wsHttpBinding>
<binding name="WsBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
Additionally you'll need to configure IIS with a binding listening on 443, referencing an appropriately named SSL certificate.
For a credential type of windows:
This corresponds to integrated Windows authentication in IIS. When set
to this value, the server is also expected to exist on a Windows
domain that uses the Kerberos protocol as its domain controller.
More details on this on the MSDN WCF transport security page
Alternatively you can use TransportWithMessageCredential. This uses SSL to encrypt the connection, and the credentials are passed in the message itself (effectively username and password in the SOAP header). In that case your binding configuration looks more like:
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Username" />
</security>
You then need to define a password validator behavior on the service to check the user and password. Here's some more info on that: http://msdn.microsoft.com/en-us/library/aa354508.aspx

TCP error code 10013 Cross Domain Policy Error with netTcpBinding Service and Silverlight Client

Was wondeirng if anybody could get me out of my cross domain policy hell.
I have a duplex WCF service which uses netTcpBining, and the client is a Silverlight 4 app. When I self host the service, then it works perfectly and my Silverlight clients can consume the service with no problems. However when I host it in IIS 7, that's when the trouble starts. When I host it in IIS I'm able to see the service at:
http://localhost/Conference/VideoConferenceService.svc
And when I add a reference to the service which is hosted in IIS, and try to call it, I get a:
CommunicationException: Could not connect to
net.tcp://localhost/Conference/VideoConferenceService.svc. The
connection attempt lasted for a time span of 00:00:03.3071892. TCP
error code 10013: An attempt was made to access a socket in a way
forbidden by its access permissions.. This could be due to attempting
to access a service in a cross-domain way while the service is not
configured for cross-domain access. You may need to contact the owner
of the service to expose a sockets cross-domain policy over HTTP and
host the service in the allowed sockets port range 4502-4534.
Or if seeing the actual error helps inspire those who have seen it before, here is what it throws at me in Reference.cs:
I have checked out almost every solution suggested regarding solving the cross-domain policy error, and I've put my clientaccesspolicy.xml in my default website root in IIS, and also in wwwroot. I've also turned off all my firewalls. I'm able to see the policy at http://localhost/clientaccesspolicy.xml
and also at http://127.0.0.1/clientaccesspolicy.xml but I still get this error.
Here is my web.config for the service hosted in IIS 7:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<gcServer enabled="true" />
</runtime>
<system.web>
<compilation debug="false" />
</system.web>
<system.serviceModel>
<services>
<service name="VideoServer.VideoConferenceService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService" contract="VideoServer.IVideoConferenceService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:4502/VideoServer/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IVideoConferenceService" portSharingEnabled="true" transactionFlow="false" transferMode="Buffered" listenBacklog="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="24.20:31:23.6470000" openTimeout="24.20:31:23.6470000" receiveTimeout="24.20:31:23.6470000" sendTimeout="24.20:31:23.6470000">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession enabled="false" />
<security mode="None">
<message clientCredentialType="None" />
<transport protectionLevel="None" clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="False" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
And here is the Silverlight client's ServiceReferences.ClientConfig file:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NetTcpBinding_IVideoConferenceService">
<binaryMessageEncoding />
<tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost/Conference/VideoConferenceService.svc"
binding="customBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService"
contract="ServiceReference1.IVideoConferenceService" name="NetTcpBinding_IVideoConferenceService" />
</client>
</system.serviceModel>
</configuration>
Has anybody got any suggestions? This annoying error has taken days of my time thus far.
Any help would be greatly appreciated.
EDIT
When I check the files being retrieved in my web sessions using fiddler, it shows that my browser is retrieving the client access policy file, so I think the error lies somewhere else and WCF is just throwing this error at me? I've also set IE9 to clear its cache everytime its close. Take a look below.
Well I just managed to get it working. Couple of points worth mentioning are that:
1. If you look at the erroneous ServiceReferences.ClientConfig that I posted above (generated by visual studio when I gave the service address as: http://localhost/Conference/VideoConferenceService.svc ) you can see that the netTcp port which is 4502, was not generated as part of the endpoint, this is what what causing the TCP error 10016 (EndpointNotFoundException) as well as TCP error 10013. The correct ServiceReferences.ClientConfig is actually:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NetTcpBinding_IVideoConferenceService">
<binaryMessageEncoding />
<tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:4502/Conference/VideoConferenceService.svc"
binding="customBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService"
contract="ServiceReference1.IVideoConferenceService" name="NetTcpBinding_IVideoConferenceService" />
</client>
</system.serviceModel>
</configuration>
2. When I was hosting my service in IIS 7, I was giving the port range 808:* as the netTcp ports, whereas I should have given 4502:* as the port range, like below:
Also from what I gathered, the website hosting the service should be on port 80, as Silverlight will look in localhost:80/ClientAccessPolicy.xml for the client access policy file.
And just for the record, for those who stumble across this same problem, this web.config managed to work in IIS:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="false" />
</system.web>
<system.serviceModel>
<services>
<service name="VideoServer.VideoConferenceService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService" contract="VideoServer.IVideoConferenceService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IVideoConferenceService" portSharingEnabled="false" transactionFlow="false" transferMode="Buffered" listenBacklog="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="24.20:31:23.6470000" openTimeout="24.20:31:23.6470000" receiveTimeout="24.20:31:23.6470000" sendTimeout="24.20:31:23.6470000">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession enabled="false" />
<security mode="None">
<message clientCredentialType="None" />
<transport protectionLevel="None" clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
Also worth noting that you don't need to put any ports or base addresses in the web.config for IIS. It will create the service endpoint using the port 4502, I tried changing it to 4503, 4522 etc. and interestingly it didn't work with those ports, only with 4502.
We had a similar problem as specified in the original post. Just to help anyone who has not been able to resolve the issue with the solutions provided above, we found that the Windows firewall on the machine hosting the service was blocking the port we were trying to connect with net.tcp through. Once we allowed the traffic through the port on that software firewall our service started working as expected.
It may be worth checking any hardware firewall you might have in place as well to allow the ranges 4502-4530 I believe for net.tcp

Configuring SSL (https) for ws2007FederationHttpBinding Endpoint 404 No Endpoint found

Another WIF related problem - can anyone point me in the direction of how to configure https in wcf for a ws2007FederationHttpBinding endpoint. I have the certificates and bindings all set-up in IIS, but whenever I try to connect to the endpoint I get a 404 error. My binding looks like this
<bindings>
<ws2007FederationHttpBinding>
<binding name="BindingConfigName">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false">
<issuerMetadata address="https://identity.localhost/issue/wstrust/mex" />
<claimTypeRequirements>
<add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" isOptional="true" />
<add claimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" isOptional="true" />
</claimTypeRequirements>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
Endpoint Looks Like
<endpoint address="https://services.localhost/MyService.svc" binding="ws2007FederationHttpBinding"
bindingConfiguration="BindingConfigName"
bindingNamespace="MyNamespace"
contract="IServiceContract">
</endpoint>
Really struggling to see what to do.
Matt

Unable to access WCF Service from Client machine

Unable to access WCF Service from Client machine
I have three projects : WCF Service (VS-2008), Windows Service (VS-2008), Client (VS-2005)
The WCF service has netTcpBinding
This service is hosted as a windows service and not on IIS
The base address for both the service (WCF and Windows) is
net.tcp://localhost:8010/WCFService.Service1/
Now when i add a service reference to the client project which is on VS-2005, It updates my app.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcpEndPoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8010/WCFService.Service1/"
binding="netTcpBinding" bindingConfiguration="netTcpEndPoint"
contract="Client.Service1.IService1"
name="netTcpEndPoint">
<identity>
<servicePrincipalName value="host/server17.domain.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
And adds Service1.map file as
<?xml version="1.0" encoding="utf-8"?>
<ServiceReference>
<ProxyGenerationParameters
ServiceReferenceUri="net.tcp://server17:8010/WCFService.Service1/"
Name="Service1"
NotifyPropertyChange="False"
UseObservableCollection="False">
</ProxyGenerationParameters>
<EndPoints>
<EndPoint
Address="net.tcp://localhost:8010/WCFService.Service1/"
BindingConfiguration="netTcpEndPoint"
Contract="Client.Service1.IService1"
>
</EndPoint>
</EndPoints>
</ServiceReference>
When I call any of the service methods I get an error stating
Could not connect to net.tcp://localhost:8010/WCFService.Service1/.
The connection attempt lasted for a time span of 00:00:02.0063936. TCP
error code 10061: No connection could be made because the target
machine actively refused it 127.0.0.1:8010.
At least it should be net.tcp://server17:8010/WCFService.Service1/
I have already tried to replace localhost with server17 in the client project... but no luck
What should I change to make it working? please help.
This is my WCF Service's App.config which is same as windows service's
app.config : as requested by Tim
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="WCFService.ServiceBehavior"
name="WCFService.Service1">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
name="netTcpEndPoint" contract="WCFService.IService1" />
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
name="mexTcpEndPoint" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8010/WCFService.Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService.ServiceBehavior">
<serviceMetadata httpGetEnabled="False" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
At a guess I'd check three things:
When you add the service reference to your client, are you adding it from net.tcp://localhost:8010/WCFService.Service1/, or are you adding it from net.tcp://server17:8010/WCFService.Service1/?
If you're adding it from server17, try using the fully qualified name of the server - i.e., server17.mydomain.com or whatever it is.
The connection error is probably related to the endpoint address you're using - the client is passing in a serverPrincipalName of "host/server17.domain.com", but you're attempting to connect to localhost.
No guarantees any of the above are the root cause, but it gives you a place to start.
EDIT
You specify the locahost in the baseAddress element, but you don't specify anything in the address attribute of the endpiont element. That's probably why it's still going to localhost.
Modify the config file for your service to either change the baseAddress to:
<baseAddresses>
<add baseAddress="net.tcp://server17:8010/WCFService.Service1/" />
</baseAddresses>
or drop the baseAddresses and specify the address in your endpoint:
<endpoint address="net.tcp://server17:8010/WCFService.Service1/"
binding="netTcpBinding"
bindingConfiguration=""
name="netTcpEndPoint"
contract="WCFService.IService1" />
Give that a try.