WCF Service (wsHttpBinding binding) behind F5 load balancer - wcf

current setup:
- i have got a WCF service with wsHttpBding, see the service config below
- i have implemented a ServiceHostFactory to solve the problem of incorrect schema location and soap addresses, modifying them from machine name to the correct server hostname
- my test client (WCFStorm) i can generate a proxy, see all the methods and invoke them successfully.
- my dev environment (client-> HTTPS -> service) works perfectly.
problems:
- prod environment (client -> HTTPS -> F5 -> HTTP -> service)
- my service is behind F5 load balancer which offloads SSL
- my test client (WCFStorm) i can generate a proxy and see all the methods but when i invoke any of the methods i get a remote server not found 404 error
my service config:
<services>
<service behaviorConfiguration="Service1Behavior"
name="MyService">
<endpoint name="secure" address="" binding="wsHttpBinding" bindingConfiguration="custBinding" contract="IService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="custBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
<message clientCredentialType="None" negotiateServiceCredential="false"
establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="Service1Behavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true" httpGetUrl="http://myserver/MyService.svc"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="6553600" />
</behavior>
</serviceBehaviors>
</behaviors>
please note that all my schema locations and soap addresses on the wsdl are correct in prod, but i simply cannot invoke any methods.
please help.

We have a similar situation and here's how we got it working.
in the service - we changed the binding to use basicHttpBinding and added a key that must be passed with every request.
in the client - we changed the http in the config to https and in the basicHttpBindings config changed the security mode to Transport with clientCredentialType="None".
Hope this helps.
UPDATE: I found this article soon after and I updated the configuration and it worked. So now we are using wsHttpBinding instead of basicHttpBinding.
http://blogs.msdn.com/b/morgan/archive/2010/04/15/setting-up-wcf-with-a-load-balancer-using-ssl-in-the-middle.aspx

The problem with your service config is that the security mode is Transport, where in reality it should be None. Because any calls to your service will be HTTP behind F5 load balancer, you can not use Transport security mode there (client -> HTTPS -> F5 -> HTTP -> service). However, when calling the service from your client, the client config will need to be Transport security mode and the endpoint address will need to have an HTTPS address.
<wsHttpBinding>
<binding name="custBinding">
<security mode="None">
<transport clientCredentialType="None" />
<message clientCredentialType="None" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>

This might be a little late for you, but here is how we do it. Once I have generated the proxy, I just change the http: in the config to https. Now, if I have to sometimes call it with ssl, and othertimes without, I will copy the config section, and give the copy a different name, and then when you construct the client, you can pass in the config name, and it will pick up the correct one.

We couldn't get this working through Layer 7 load balancing - there was various error messages returned from the service. Instead it's set up on Layer 4 load balancing with no issues.

Related

WCF Service over HTTPS giving errors

I have made a WCF service with configuration as follows:
<!-- This is the binding for SSL-->
<wsHttpBinding>
<binding name="SSLBinding">
<security mode="Transport" >
<transport clientCredentialType="None" ></transport>
</security>
</binding>
</wsHttpBinding>
<!-- SSL Binding Ends here.-->
</bindings>
<behaviors>
<serviceBehaviors>
<!-- This is the behavior we have defined for SSL configuration-->
<behavior name="SSLBehavior">
<serviceMetadata httpsGetEnabled="True"/>
</behavior>
<!-- SSL Behavior Ends here -->
</serviceBehaviors>
</behaviors>
<services>
<!-- Service configured alongwith its Mex Endpoint-->
<service name="CalculatorService.Service1" behaviorConfiguration="SSLBehavior">
<endpoint contract="CalculatorService.IService1" name="SSLAddress" binding="wsHttpBinding" bindingConfiguration="SSLBinding"></endpoint>
<endpoint name="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
I have used the following tutorial to host SSL on WCF service on IIS 5.1
http://www.codeproject.com/Articles/36705/7-simple-steps-to-enable-HTTPS-on-WCF-WsHttp-bindi
I am getting the error as
A binding instance has already been associated to listen URI
'https://wd-xpa7kyy12d3.XXXX.com/CalculatorService/Service1.svc'. If two endpoints want to share the same ListenUri, they must also share the same binding object instance. The two conflicting endpoints were either specified in AddServiceEndpoint() calls, in a config file, or a combination of AddServiceEndpoint() and config.
In endpoint named "SSLAddress" I added "address" as 'https://wd-xpa7kyy12d3.XXXX.com/CalculatorService/Service1.svc', but was not able to add service reference with this URL, and had to specifically give WSDL path.
Even after providing WSDL path and adding service reference successfully to console application, when the client proxy was executing the methods, it was giving error. So I removed the address attribute from endpoint and now this issue is coming. I am not sure what is wrong in current configuration? Thanks for help.
try adding
address="mex"
to your meta data endpoint.
the address specified ends up being a relative path, so it will be given
https://wd-xpa7kyy12d3.XXXX.com/CalculatorService/Service1.svc/mex
as an address. The other endpoint will remain at
https://wd-xpa7kyy12d3.XXXX.com/CalculatorService/Service1.svc

WCF On HTTPS Generates "The provided URI scheme 'https' is invalid; expected 'http'."

I have been googling everywhere I can possibly find (including here on Stackoverflow) to figure out an error I've got trying to deploy a WCF service to IIS 7.5 on Windows 7 x64 that runs only over SSL with basic HTTP authentication. I've got a site in IIS which has a binding to port 50443 for HTTPS with a self-signed cert. (I can't use the standard port 443, as we plan on deploying this to IIS on a server which is already running Tomcat which is listening on 80 and 443.)
This is the web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="SSLBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="HelloWorldWcf.HelloWorldWcfService">
<endpoint name="HelloWorldWcf.HelloWorldWcfService"
address="https://mylaptop:50443/HelloWorld/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="SSLBinding"
contract="HelloWorldWcf.IHelloWorldWcfService"/>
<endpoint address="https://mylaptop:50443/HelloWorld/Service1.svc/mex"
binding="mexHttpsBinding"
contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
If I browse to the service endpoint address and enter the basic authentication credentials manually, I get the following exception error message displayed in my browser:
The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: context.ListenUriBaseAddress
This is the same error I got trying to run a WCF client against a similar service, except that it ends with "Parameter name: via" (because the parameter name of the method that shows up in the call stack, "System.ServiceModel.Channels.TransportChannelFactory`1.ValidateScheme(URI via)", is in fact "via").
I've tweaked the server and client config files so many times I've lost track, but the web.config file above is my best guess so far--and it doesn't even work from a browser, much less a WCF client.
What do I need to do to access a WCF service hosted in IIS 7.5 on a nonstandard SSL port with basic HTTP authentication over HTTPS? Help! (& Thanks!)
try add this to binding
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
Arrrrgh! Okay, the remaining steps to get it to work:
Replace my <security> node in the web.config with burning_LEGION's.
Eliminate the "mex" endpoint from the web.config. (This allowed me to get to the usual "You have created a service" friendly web page in my browser.)
Escaped the backslash in the "DOMAIN\username" string I was assigning to HelloWorldWcfServiceClient.ClientCredentials.UserName.UserName in the client C# code. (Did I say "arrrrgh!"? Man, is my face red.) This eliminated the error I got after steps 1 and 2:
System.ServiceModel.Security.MessageSecurityException: "The HTTP
request is unauthorized with client authentication scheme 'Basic'. The
authentication header received from the server was 'Basic
realm="mylaptop"'.---> System.Net.WebException: The remote server
returned an error: (401) Unauthorized.
I got the idea for step 2 from here which made me think mex was unhappy with HTTPS, and for step 3 from here where I noticed the user name was #"domain\username", not "domain\username".
+1 to burning_LEGION for the assist!
So, the unanswered questions: (1) why does the security/message node have any effect on a configuration that doesn't use message security (only transport security)? (2) what's the point of the mex endpoint if it just interferes with normal operation? (3) If mode="TransportCredentialOnly" doesn't work with HTTPS, why don't I get an error indicating this?

wsHTTPBinding over HTTPS causes Error 400 'Bad Request'

I've been trying to create a simple service to allow messages to be logged onto a remote server via WCF, which all worked fine until I published the service to the live environment, which uses HTTPS.
After some searching, I found that I needed to change my ServiceConfig to account for the different protocol. I used a combination of these two articles:
How to configure WCF services to work through HTTPS without HTTP binding?
WCF Bindings needed for HTTPS
Having made the recommended changes to my config, I seem to be in a state where I can add the live service as a WCF reference in VS2010, but when I use IE to browse to the service or the mex address, I'm consistently receiving an 'HTTP 400 Bad Request' error.
In terms of using the service I can seem to run it successfully but the mex just doesn't want to work through IE.
The Service itself is being hosted on Windows Server 2003 R2 Standard Edition SP2 Running IIS 6.0 with no load balancing.
I'm really at a loss at this point, I've spent 3-4 days messing around with this but I can't seem to make any progress. So any help would be greatly appreciated.
See below the Server service config in question:
<system.serviceModel>
<services>
<service name="mycorp.Callback.SecPayService" behaviorConfiguration="mycorp.Callback.SecPayServiceBehavior">
<endpoint address="https://myserver.co.uk/SecPay/SecPayService.svc"
binding="wsHttpBinding" bindingConfiguration="TransportBinding"
contract="mycorp.Callback.ISecPayService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mycorp.Callback.SecPayServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="TransportBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
If you are hosting your service in IIS then just have the endpoint elements address value to empty string as the address for the endpoint is assigned by IIS

Configuring WCF Transport security for IIS6 over SSL

I've been attempting to set up WCF transport security using SSL on IIS6.
The client is on a seperate machine on the same domain.
I understand the premise of certificates, root CA etc and have a working set of certs for message security and can use these no probs in the same enviroment set up. (i've learn't a lot over the last week :)
I'm having an nightmare trying to get my client to authenticate against the IIS 6 service when i switch it to SSL. Always recieving 'annonymous authetication not allowed' when calling.
IN IIS i have
a root signed CA cert set on the site for SSL port 443
(if i browse the https:// svc page i can see the IE padlock and the page says you need a cert to communicate)
under secure communications i have
require SSL channel
require 128 bit encryption
require client certificates
enable client certificate mapping (set up with a many to 1 mapping to a admin account on the IIS box for now matched on the cert subject O field )
under web site security (authentication and access control)
Anonymous access = ON
Intergrated Windows Authentication = OFF
basic Authentication = ON
For the client wsHttpBinding i have a certificate ready to authenticate and a custom endpoint behaviour to supply this info but i don't think its getting this far!
UPDATED SERVER CONFIG
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="CertificateWithTransport">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WCFServiceCertificate.Service1" behaviorConfiguration="credentialConfig">
<endpoint address="https://svnvmig02/Service1.svc"
binding="wsHttpBinding"
bindingConfiguration="CertificateWithTransport"
contract="WCFServiceCertificate.IService1">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="credentialConfig">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
UPDATED CLIENT CONFIG
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://svnvmig02/Service1.svc" binding="wsHttpBinding" behaviorConfiguration="CustomBehavior"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="svnvmig02" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
EDIT:
Probably worth mentioning that my VS projects are 3.5 but IIS6 is running .net4
With the amended config (thanks Fabio ;) i can now IE browse the address https://svnvmig01/Service1.svc from the client machine and see the generated svc page which allows me to click on the wsdl URl which is also available.
The majority of the pages i have found on the net refer to selfhosting or IIS7....I'm hoping IIS7 support is better ;)
Any help would be greatly appreciated :)
Your config includes:
https://svnvmig02:8091/Service1.svc
The normal port for ssl is 443.
It may be that the request is not going to the site that you expect it to go to. Therefore, you are getting and unexpected error message.
Check the IIS logs to make sure which site is receiving the request.
I think your issue here may be that you have IIS set to:
Anonymous access = OFF
I use transport security on several of my servers, and all the IIS6 ones have that setting ON, not OFF. This also corresponds to the error message you provided:
'annonymous authetication not allowed'
Without anon access off, IIS will either want the user to enter a username/password, or pass along a windows / active directory / kerberos credentials.

Wcf Http and Https

Help please!!
I had the following set up working perfectly:-
WCF Service Library hosted in web site on local IIS 7
Silverlight Application on a web site on local IIS 7 using above services
The solution I am writing is for intranet and not internet use, however I have been told by my bosses that it needs to be over Https. I am using Windows Authentication.
Below is a chunk of the config file for one of the service endpoints (changed to remove company info etc):-
<services>
<service behaviorConfiguration="stdHttpBehavior" name="WcfServiceLibrary.StaticDataService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="windowsHttpBinding"
name="StaticDataService" contract="WcfServiceLibrary.ServiceContracts.IStaticDataService" />
<endpoint address="mex" binding="mexHttpBinding" name="" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfServiceLibrary/StaticDataService/" />
</baseAddresses>
</host>
</service>
<behaviors>
<serviceBehaviors>
<behavior name="stdHttpBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
To experiment with Https I created a 'Self-Signed Certificate'. I then added https to the Default Web Site bindings and changed the two web sites to require SSL and also changed the relvant URIs in the config files. I managed to get this to work but now I want to go back to standard Http and finish the project in that mode as it was easier to work with. I changed all the settings back (and I have checked these extremely carefully).
Now I get this error if I try to downoad the Service definition in the Silverlight project: -
'Could not find a base address that matches scheme https for the endpoint with binding BasicHttpBinding. Registered base address schemes are [http].'
If I put back the certificate and binding in IIS. The Service definition appears to download OK, however it references an https URI and therefore none of the actual service calls work as they are http adresses!
I tried adding a new web site to host the service but got the same errors.
I have been trying to solve this for the last couple of days but cannot find an answer. It seems as though there is a hidden reference somewhere and not in my project as it continued with a new web site added to IIS.
To use SSL over HTTP under Basic HTTP binding, you need to switch your endpoint to use Transport-level security. In your case you will also want to indicate the client credential type:
<bindings>
<basicHttpBinding>
<binding name="windowsHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
<message />
</security>
</binding>
</basicHttpBinding>
</bindings>
It may seem obvious, but did you change the security mode on the windowsHttpBinding binding configuration to BasicHttpSecurityMode.None?
<bindings>
<basicHttpBinding>
<binding name="windowsHttpBinding">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
Related resources:
Transport Security Overview
BasicHttpSecurityMode Enumeration