WCF HTTPS and multiple sites in IIS - wcf

I am trying to configure IIS to host one set of binaries in two IIS websites. So we want to be able to access the urls:
http://external.example.com/ADataService
https://external.example.com/ADataService
http://internal.example.com/ADataService
internal.example.com and external.example.com are set up as different IIS sites to allow us to assign them different application pools. However when I added HTTPS support to our web.config, the internal HTTP support stopped working; http://internal.example.com/ADataService now returns the error:
Could not find a base address that matches scheme https for the endpoint with binding CustomBinding. Registered base address schemes are [http].
Here are the details of our web.config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<customBinding>
<binding name="jsonCustomMapper">
<webMessageEncoding webContentTypeMapperType="Service.JSONCustomMapper, Service" />
<httpTransport manualAddressing="true" />
</binding>
<binding name="httpsjsonCustomMapper">
<webMessageEncoding webContentTypeMapperType="Service.JSONCustomMapper, Service" />
<httpsTransport manualAddressing="true" />
</binding>
</customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Service.Service" behaviorConfiguration="defaultBehavior">
<endpoint address="json" binding="customBinding" bindingConfiguration="jsonCustomMapper" behaviorConfiguration="jsonBehavior" contract="Service.IJSONService" />
<endpoint address="json" binding="customBinding" bindingConfiguration="httpsjsonCustomMapper" behaviorConfiguration="jsonBehavior" contract="Service.IJSONService" />
</service>
</services>
</system.serviceModel>
From what I understand multipleSiteBindingsEnabled="true" and HTTPS do not mix, but I don't understand what resources they would be sharing? If we have internal.example.com and external.example.com hosted in different app pools, I thought they would have process isolation?

seems that adding an HTTPS certificate to the site for "internal.example.com" fixed the issue. Note: without this certificate we were not able to access internal.example.com over either HTTP or HTTPS, with certificate both mechanisms work correctly.

Related

WCF Rest Service - worked great ... Until SSL

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.

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 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!

Configure WCF to ignore authentication requirements inside IIS

Scenario:
Two websites (example.com, admin.example.com) that share the same wwwroot folder.
example.com allows only anonymous access
admin.example.com allows only windows authentication.
/Service/Awesome.svc returns a json object
Accessing the Awesome service using example.com works, while admin.example.com throws a NotSupportedException; "Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service."
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="WcfServices.AwesomeService"
behaviorConfiguration="serviceBehavior">
<endpoint address="" binding="webHttpBinding"
contract="WcfServices.IAwesomeService"
behaviorConfiguration="jsonBehavior" />
</service>
</services>
</system.serviceModel>
How do I configure WCF to ignore the authentication requirement? I want the same behavior as if this were a web service or handler, just execute and return the awesome json object.
I think you're out of luck here. Give AWesome.svc anonymous access, and give anon access a user account that has no access to sensitive resources.
It sounds like you have two copies of the service, one under the website example.com and the other under admin.example.com. If admin.example.com needs IIS integrated (challenge/response) authentication then you're WCF service binding needs to be in Transport mode because IIS requires all admin.example.com resources to be Windows authentication. Try this configuration:
<bindings>
<basicHttpBinding>
<binding name="Binding1">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
If this doesn't work for you, you may want to try hosting the services in their own virtual directy so they are not at the mercy of what the website needs for security.
Good Luck.

Why can't I get my Azure, WCF, REST, SSL project working? What am I doing wrong?

I'm trying to get SSL, WCF and REST under Azure, but the page won't even load.
Here are the steps I followed:
1) I mapped the www.mydomain.com CNAME to my azuresite.cloudapp.net
2) I procured an SSL certificate for www.mydomain.com and properly installed it at my azuresite.cloudapp.net hosted service project
3) I deployed my WCF REST service to Azure and started it. Below is my web.config configuration.
The http (non-https) binding version worked correctly. My service URL, http: //www.mydomain .com/service.svc/sessions worked just fine.
When I deployed the project with the web.config below, enabling SSL, https: //www.mydomain .com/service.svc/sessions does not even pull up at all.
What am I doing wrong?
<system.serviceModel>
<services>
<service name="Service">
<!-- non-https worked just fine -->
<!--
<endpoint address="" binding="webHttpBinding" contract="IService" behaviorConfiguration="RestFriendly">
</endpoint>
-->
<!-- This does not work, what am I doing wrong? -->
<endpoint address="" binding="webHttpBinding" bindingConfiguration="TransportSecurity" contract="IService" behaviorConfiguration="RestFriendly">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RestFriendly">
<webHttp></webHttp>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
Did you add the https endpoint to your web role in the ServiceDefinition.csdef file?
It should look something like this:
<WebRole name="WebRole">
<InputEndpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
<InputEndpoint name="HttpsIn" protocol="https" port="443" />
</InputEndpoints>
</WebRole>
See http://blogs.msdn.com/jnak/archive/2009/05/12/https-endpoint-on-windows-azure.aspx for more info.
You may be missing a service behaviour. Try adding this:
<serviceBehaviors>
<behavior name="RestService">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
Then when you define your service:
<service behaviorConfiguration="RestService" name="WebService.Rest">
Edit
Another thing that could be the problem, is that the request is not reaching your webrole. Have you set up an inputEndpoint for SSL? see Link