WCF Rest Service - worked great ... Until SSL - wcf

I have a WCF Rest service that has been running very smoothly. I just got my SSL cert and installed it in IIS, added an auto redirect to https (basically, forcing https). Now, if I go to "website/ServiceDirectory/Service.svc, I still get the "You have created a service" message, but when I attempt to actually call the service, I'm getting 404 not found. I have already looked through numerous articles. I've disabled http/enabled https. I've ensured I enabled "Transport" security in the binding..Not sure if I'm just missing something or what's going on. Here's my web config, but I'm beginning to think it may be something in IIS
<system.serviceModel>
<client>
<endpoint address=""
binding="webHttpBinding" bindingConfiguration="WebBinding"
behaviorConfiguration="web"
contract="EngageService.IEngage" name="win"/>
</client>
<bindings>
<webHttpBinding>
<binding name="WebBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<services>
<service behaviorConfiguration="ServiceBehavior" name="EngageService.Engage1">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding"
contract="EngageService.IEngage" bindingConfiguration="WebBinding" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp defaultOutgoingResponseFormat="Xml"/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<!--<add binding="basicHttpBinding" scheme="http"/>-->
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
In IIS, the service is configured as an application, and as I stated it was working perfectly before I switched to https. Does anyone either see something wrong with my config file, or know of any IIS configuration items I may need to check/change?
Thanks

Ok so this boiled down to the protocolmapping section. It seems that without this mapping, webhttpbinding defaults to http. Added the webhttpbinding, including the entire section to make it easier to spot - hopefully this helps someone else one day.
<protocolMapping>
<!--<add binding="basicHttpBinding" scheme="http"/>-->
<add binding="basicHttpsBinding" scheme="https"/>
<add binding="webHttpBinding" scheme="https" bindingConfiguration="WebBinding"/>
</protocolMapping>
If you have tried all of the other articles and still can't get it - try the above. It breaks http, but I imagine only because you're stealing the endpoint. If you configured a secondary http binding, I would bet it would work perfectly.

Related

Moving WCF service to IIS6 with SSL enabled

I ran my WCF service on the server without SSL enabled and now I moved it to one with SSL enabled and I am getting the following error:
Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https].
Below are my settings:
<bindings>
<basicHttpBinding>
<binding name="basicHTTP">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows">
</transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="basicBehavior" name="ProjectName.MyService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHTTP" contract="ProjectName.IMyService"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="basicBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
How can I fix this error?
You need to define a binding for basicHttps. This is a very simple settings that works for SSL:
<system.serviceModel>
<bindings>
<basicHttpsBinding>
<binding name="BasicHttpBinding_IMyService" />
</basicHttpsBinding>
</bindings>
<client>
<endpoint
name="BasicHttpBinding_IMyService"
address="https://MyURL/MyService.svc/soap/"
binding="basicHttpsBinding"
bindingConfiguration="BasicHttpBinding_IMyService"
contract="ClientServiceReference.IMyService" />
</client>
</system.serviceModel>
Note: The endpoint needs to be defined and its URL is https.
Also, make sure that in production environment, you are not sending the exception details back to the caller (that would be considered a security hole in your system because exceptions can reveal too much information to hackers). You must change this line:
<serviceDebug includeExceptionDetailInFaults="false"/>
Fixed the issue by specifying security mode as Transport and using webHttpBinding

WCF Rest - mixing HTTP and HTTPS in one ServiceContract

I currently have a Http Rest WCF4 service, defined by the ServiceContract IEventService which is exposed only over HTTP.
I have been tasked with making some of the OperationContracts to work only over HTTPS So I have split those methods into a seperate ServiceContract called IEventServiceHTTPS
Hosting this on my dev box using IIS7.5 with a self-signed certificate, the methods which are part of the IEventServiceHTTPS are called fine over HTTPS and not over HTTP, as expected.
However the HTTP methods exposed by IEventService now do not work.
I get the following when trying to access the HTTP methods:
HTTP Error 403.4 - Forbidden
The page you are trying to access is secured with Secure Sockets Layer (SSL).
web.config with my changes:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true">
<serviceActivations>
<add service="Api.EventService" relativeAddress="EventService.svc" factory="Api.UnityServiceHostFactory"/>
</serviceActivations>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="Api.EventServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="Api.EventServiceBehavior" name="Api.EventService">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="WebBehavior" bindingConfiguration="webBindingHTTP" contract="Api.IEventService"/>
**<endpoint address="" binding="webHttpBinding" behaviorConfiguration="WebBehavior" bindingConfiguration="webBindingHTTPS" contract="Api.IEventServiceHTTPS"/>**
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBindingHTTP">
<security mode="None"></security>
</binding>
**<binding name="webBindingHTTPS">
<security mode="Transport">
</security>
</binding>**
</webHttpBinding>
</bindings>
</system.serviceModel>
Any help would be greatly appreciated, thanks.
I believe this error is originating because of IIS vdir [SSL settings]-> Require SSL -> true. If you want both http and https endpoints accessible in the same service then uncheck this setting as this will prevent you from doing unsecure http in the vdir.

wcf with basic authentication through reverse proxy

I have a Web Service which uses basic authentication with ssl through a reverse proxy. It has already cost me quite some time to figure out how to get this working and I still fail to get it fully working.
if you type in the url in the browser https://domain.com/service.svc, it asks for credentials and if correct, you get the overview page of the service.
So that seems to be okay.
But when I try to add the Service to Visual Studio 2010, I get the following error:
Metadata contains a reference that cannot be resolved:
The document format is not recognized (the content type is 'text/html; charset=utf-8').
Metadata contains a reference that cannot be resolved: 'https://domain.com/service.svc'.
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm=NTLM'.
The remote server returned an error: (401) Unauthorized.
If the service is defined in the current solution, try building the solution and adding the service reference again.
Here is my web.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<!--<httpsTransport authenticationScheme="Basic"/>-->
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None" proxyCredentialType="Basic" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfService1.PortalService" behaviorConfiguration="NorthwindBehavior">
<host>
<baseAddresses>
<add baseAddress="https://domain.com/" />
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyBinding" contract="WcfService1.IPortalService">
<!--<identity>
<servicePrincipalName value=""/>
</identity>-->
</endpoint>
<!--<endpoint address="mex" binding="basicHttpBinding" bindingConfiguration="MyBinding" name="mex" contract="WcfService1.IPortalService"></endpoint>-->
</service>
</services>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="https://domain.com/"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<!--<extensions>
<bindingElementExtensions>
<add name="httpsViaProxyTransport" type="WcfService1.HttpsViaProxyTransportElement, WcfService1"/>
</bindingElementExtensions>
</extensions>
<bindings>
<customBinding>
<binding name="UserNamePasswordSecured">
<textMessageEncoding />
<security authenticationMode="UserNameOverTransport" />
<httpsViaProxyTransport />
</binding>
</customBinding>
</bindings>-->
<behaviors>
<serviceBehaviors>
<behavior name="NorthwindBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles"/>
<serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"/></serviceCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="SampleEndpointBehavior">
<!--<wsdlExtensions location="http://domain.com/PortalService.svc" singleFile="true"/> -->
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
I tried numerous things like following this post: http://blog.hackedbrain.com/2006/09/26/how-to-ssl-passthrough-with-wcf-or-transportwithmessagecredential-over-plain-http/ but not very succesful.
I also tried to add site bindings to http because the wsdl is generating the server name instead of the domain name, so maybe there is something wrong at that end as well...
So hopefully someone can provide me with some pointers!
Note that the web.config file has some 'junk' in it because of trying with million different settings...

Can't host tcp based wcf service on IIS, Cannot obtain Metadata from net.tcp://localhost/TestApp2/MyService error pops up

I have a simple test purpose WCF service. I'm trying to host it under IIS 7.5 ( Windows 7 ) but no luck so far. I'm getting error
Cannot obtain Metadata from net.tcp://localhost/TestApp2/MyService
I have a web site TestApp2 under Default Web Site, I enabled tcp on Default Web Site and TestApp2. Here is my web.config file, while I realize that this error simply states that I didn't have endpoint for metadata exchange, I can't see what's the problem because I included endpoint for metadata exchange.
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyService">
<endpoint address="net.tcp://localhost/TestApp2/MyService"
binding="netTcpBinding"
bindingConfiguration="PortSharingBinding"
contract="II7WcfService.IService1" />
<endpoint address="MEX"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost/TestApp2/MyService" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="PortSharingBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="False" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Thanks.
My guess is your service isn't actually called MyService but rather it is in a namespace. This means your declared endpoints are not getting picked up, and the default ones (which doesn't include IMetadataExchange) are being used instead.
Add the name of your namespace to the attribute in the config and it should work.

WCF service not accessible in Windows Server 2008

I recently built a WCF Service, and now I'm deploying it to Windows Server 2008. Right now, we don't have secure protocol turned on. But we will. I'd like to get it working either way. In the site, I've had Anonymous authentication enabled as well as Forms authentication. The reason I did this was to prevent the authentication popup on the iPad, Android and Internet Explorer. So now they just get to the Login screen. Oh and I did activate WCF in Windows features. If you're also knowledgeable about making this https ready, I'd also like to figure that out. Thanks!!
I'm getting this error when I try pasting in the *.svc PATH into the URL.
System.ServiceModel.ServiceActivationException:
The service
'/WCFServices/Accessioning/QuickDataEntryService.svc'
cannot be activated due to an
exception during compilation
Here is my web.config configuration thus far.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<!--<baseAddressPrefixFilters>
<add prefix="http://localhost/" />
</baseAddressPrefixFilters>-->
</serviceHostingEnvironment>
<behaviors>
<endpointBehaviors>
<behavior name="AspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
<!-- Watch this section when adding a new WCF Service! New behaviors will be added; just delete them and use "ServiceBehavior" -->
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService">
<endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding"
contract="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<!--<service name="A.LIMS.UI.Web.WCFServices.Accessioning.IQuickDataEntryService"
behaviorConfiguration="ServiceBehavior">
<endpoint behaviorConfiguration="AspNetAjaxBehavior"
binding="webHttpBinding"
contract="A.LIMS.UI.Web.WCFServices.Accessioning.IQuickDataEntryService" />
</service>-->
<!-- Watch this section when adding a new WCF Service! Duplicate the "QuickDataEntryService" above for an example, but change the fully qualified name -->
</services>
</system.serviceModel>
I have no clue what caused the exception above, but here was the final verdict. There were a lot of things required for WCF and using an SSL certificate (HTTPS protocol). Pardon the formatting.. I don't like how Stack Overflow sometimes puts the code into a block and sometimes it doesn't.
The following were required for the web.config on HTTPS:
Here are some places that required the "requireSSL" attribute:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" timeout="30" protection="All" requireSSL="true" />
</authentication>
<httpCookies httpOnlyCookies="false" requireSSL="true" domain="" />
Notice the "s" in "httsGetEnabled" below:
<behaviors>
<endpointBehaviors>
<behavior name="AspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpsGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Bindings (missing in non-SSL web.config):
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
Services (notice the "s" in "mexHttpsBinding"):
<services>
<service behaviorConfiguration="ServiceBehavior" name="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService">
<endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
Last but not least. I'm not using .NET 4.0, but I did try .NET on a different machine. With .NET 4.0 I couldn't get the WCF services to work without having this configured to the actual URL being used. If there were two domains for the same IP, WCF only worked with the domain in this block inside the system.ServiceModel XML block in the web.config. I did not test https in the .NET 4.0, so I'm assuming the protocol on the URL would be https below:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://subdomain.domain.com/" />
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
Oh, I also had to turn on WCF on the Windows Server 2008 box. And it required a server reboot!