WCF Rest service does not work over HTTP in IIS 8 - wcf

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>

Related

WCF web.config file settings for IIS hosting and SSL

After hours of searching for examples, most of which contain only snippets of methods but not the 'whole picture' I am asking for guidance. Starting with the out-of-the-box web.config Visual Studio creates with a new WCF Service, I wrote my basic web service. When you run in debug, WCF Test Client shows the functions that you can test. This is great. Now, wanting to move the code to IIS (first on my local machine, then next to the web server using SSL), I added some code I found on the web. I did have my configuration working at one point but managed to change it so much that I lost the original configurations. So, which that, I have this:
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<services>
<service name="TaskTrackerAppService.Service1" behaviorConfiguration="">
<endpoint address=""
binding="webHttpBinding"
contract="TaskTrackerAppService.IAppWebService"
behaviorConfiguration="WebBehavior"></endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" bindingConfiguration=""></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="TaskTrackerAppService.IAppWebService"></binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="TaskTrackerAppService.IAppWebService"
contract="TaskTrackerAppService.IAppWebService"></endpoint>
</client>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
I configure my client desktop application service reference to point to the local IP http:192.168.0.100:90/AppWebService.svc. Then when I run my client application I get an error:
Could not find default endpoint element that references contract 'ServiceReference.IAppWebService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
So I'd like to get the web.config settings corrected. Then deploy to a hosted IIS service where SSL is ready. As a bonus, is there is way to configure the endpoints such that I can still run debugger and get WCF Test Client. In the once working config WCF test stopped working. Can it support both simple and hosted configurations?
Thanks.
The <client> section in the <system.serviceModel> is used by client application to specify the "ABC" properties (Address, Binding, and Contract) of the service endpoint. You should have that section in your desktop application so you can simply remove it from your server configurations.
The <client> section in the app.config of your desktop application should, however, have the same "ABC" properties as the service endpoint. Since your service binding is webHttpBinding the client should also have webHttpBinding as binding but I can see that the bindingConfiguration it is referring to, TaskTrackerAppService.IAppWebService is actually a basicHttpBinding so that is a misconfiguration.
Further, since your production environment is using SSL so your production web.config should have binding configuration for SSL something similar to this:
<bindings>
<webHttpBinding>
<binding name="webBindingHTTPS">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
with the following endpoint configuration:
<endpoint address=""
binding="webHttpBinding"
contract="TaskTrackerAppService.IAppWebService"
behaviorConfiguration="webBindingHTTPS"></endpoint>
The best way to achieve this is to use web.config transformation syntax. In that case, your Release web.config could have the following elements:
<bindings>
<webHttpBinding>
<binding name="webBindingHTTPS" xdt:Transform="Insert">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<endpoint address="" xdt:Transform="Replace" xdt:Locator="Match(name)"
binding="webHttpBinding"
contract="TaskTrackerAppService.IAppWebService"
behaviorConfiguration="webBindingHTTPS">
</endpoint>
In this way, whenever you project is built in Debug mode it will be configured withoud SSL and whenever is built in Release mode, it will use SSL.

Custom Domain for Azure Cloud Service with SSL

I'm trying to expose an Azure Cloud Service using https with a custom domain, but I get an error: "The requested service, 'https://mydomain.net/myservice.svc' could not be activated. See the server's diagnostic trace logs for more information."
Regarding the custom domain: I've followed the steps at https://www.windowsazure.com/en-us/develop/net/common-tasks/custom-dns/#header-1 for the second option, "A record": in godaddy's Zone File Manager, I have an A record configured for the "#" host that "Points To" myservice's "Public Virtual IP Address" (as found in the Azure portal). It seems to me that the fact I'm getting "the service could not be activated" means the A record is working, but I'm not certain.
Regarding the https: I've followed the steps at http://www.31a2ba2a-b718-11dc-8314-0800200c9a66.com/2011/06/how-to-get-and-install-ssl-certificate.html. In brief: I purchased a cert from godaddy using a CSR from my dev machine for mydomain.net, completed the CSR on my dev machine using the friendly name mydomain.net, exported it to mydomain.net.pfx, using that file, uploaded the cert to my cloud service in Azure and configured my WebRole in VS with the cert, and published the web role project to Azure.
On the client side (WP7):
<bindings>
<basicHttpBinding>
<binding name="BasicHttpsBinding_IMyInterface"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint name="BasicHttpsBinding_IMyInterface"
address="https://mydomain.net/myservice.svc"
contract="MyService.IMyInterface"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpsBinding_IMyInterface" />
</client>
Note: I didn't use CName because my cert isn't for a subdomain and it isn't a wildcard.
From my searches, I get the impression this is working for other folks and I can't figure out what I'm doing differently.
yep - you need a matching endpoint specified in the server config. The following is a complete example of a web.config file for a WCF service using HTTP transport security (from http://msdn.microsoft.com/en-us/library/hh556232.aspx):
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="MySecureWCFService.Service1">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="MySecureWCFService.IService1"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>

WCF Endpoint address problems

I created a WCF web service and created a new site in IIS (7). I created a new port (8002) for http requests. I can browse to the site and get the typical "You do not have permission to view this directory ..." so I know the site is working. However, I set my endpoint address to "http://1.1.1.1:8002" in my web.config (where 1.1.1.1 is replaced with my actual real IP address). when I browse to the service with http://1.1.1.1:8002/service.svc I get page cannot be found error. There is a service.svc in the root folder of the site. What is wrong with the setup?
Here is the web.config file if helpful (again, the 1.1.1.1 is replaced with my real IP address):
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicBinding">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WcfService.ServiceBehavior" name="WcfService.Service">
<endpoint address="http://1.1.1.1:8002" binding="basicHttpBinding" bindingConfiguration="BasicBinding" contract="WcfService.IService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService.ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
You cannot control the address of your service in configuration file when hosting in IIS. You can control only relative address of the endpoint - it is relative to .svc file.
So if you host the service in the site http://YourIP:8002 its address is http://YourIP:8002/Service.svc and the address element in the endpoint is relative to this address. But I expect you don't host the service directly in the site. You have some application in the site and the name of the application is part of the URL: http://YourIP:8002/YourApplicationName/Service.svc Actually every folder used to nest the service is part of the URL.

net.tcp hosted in IIS7.5 on windows 7 virtual machine using .NET 4.0

I have the simplest WCF service which works when hosted in IIS using basicHttp binding. It has one empty method called DoNothing which takes no parameters and returns a void
void DoNothing()
However I cannot get it to work when trying to host it in IIS using net.tcp.
I am assuming it is the configuration, as the same service code should work regardless of binding used.
I have enabled non-http activation. I am using a different port 12345 to avoid any clashes. The website and service is set up to use net.tcp binding.
The Net.Tcp ListenerAdaptor and Net.Tcp Port Sharing services are running
I can get the metadata to use WcfTestClient to test the service.
The error I get is
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.8597984'.
The inner exception is
An existing connection was forcibly closed by the remote host
I thing I have checked everything. I have tried calling it remotely and locally on the virtual machine
I can only think it is a simple config error or a security issue. The virtual machine is not in a domain. I have disabled the firewall completely on the virtual machine.
Has anyone had the same issue, and has a resolution. Or does someone have a very simple (full) example of how to host a net.tcp service in IIS, whih they could post
Here is my web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="PortSharingBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="SimpleNetTcpService.Service">
<endpoint address="net.tcp://192.168.0.2:12345/SimpleNetTcpService/Service"
binding="netTcpBinding" bindingConfiguration="PortSharingBinding"
contract="SimpleNetTcpService.IService" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I found the issue. I just removed the address attribute from the service element
was
<service name="SimpleNetTcpService.Service">
<endpoint address="net.tcp://192.168.0.2:12345/SimpleNetTcpService/Service"
binding="netTcpBinding" bindingConfiguration="PortSharingBinding"
contract="SimpleNetTcpService.IService" />
now
<service name="SimpleNetTcpService.Service">
<endpoint
binding="netTcpBinding" bindingConfiguration="PortSharingBinding"
contract="SimpleNetTcpService.IService" />
Works fine now

Publish WCF Service in IIS with support for both HTTP and HTTPS

I have a WCF-Service configured with two endpoints using webHttpBinding, one for http and the other for https. They use the same address, the endpoints just differ by the used protocol:
<services>
<service name="Blubb.ClientService">
<endpoint binding="webHttpBinding" bindingConfiguration="webBindingConfig" behaviorConfiguration="webBehaviour"
contract="Blubb.Contracts.IClientService"/>
<endpoint binding="webHttpBinding" bindingConfiguration="sslWebBindingConfig" behaviorConfiguration="webBehaviour"
contract="Blubb.Contracts.IClientService"/>
</service>
<services>
using the following behaviours and bindings:
<behaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webBindingConfig">
<security mode="None"/>
</binding>
<binding name="sslWebBindingConfig">
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
Both endpoints work fine when I have the certificate installed on IIS 6.
When the certificate is not installed, the HTTPS-Endpoint certainly won't work. But the HTTP-Endpoint doesn't work either. It fails with an irritating exception: when I access the service with http://localhost:8080/ClientManagement/ClientService.svc/GetPackageInfo the exception is:
Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http].
which is irritating because I didn't request an HTTPS-URL.
Now when I split the service into two, the HTTP-Access also works on the IIS on which the SSL-Certificate is not installed:
<services>
<service name="Blubb.ClientService">
<endpoint binding="webHttpBinding" bindingConfiguration="webBindingConfig" behaviorConfiguration="webBehaviour"
contract="Blubb.Contracts.IClientService"/>
</service>
<service name="Blubb.ClientServiceSecure">
<endpoint binding="webHttpBinding" bindingConfiguration="sslWebBindingConfig" behaviorConfiguration="webBehaviour"
contract="Blubb.Contracts.IClientService"/>
</service>
</services>
The problem now is that the client has to use two different endpoints instead of just changing the protocol. We have a system where the customer can turn on SSL via our Configuration-Tool depending on their security needs. But I don't want to force them to change the web.config of the WCF-Service.