I have an WCF REST service with only GET access. I'd like to make it obligatory to use SSL only on several of the service functions.
How can this be accomplished?
Thanks!
Intermixing HTTP and HTTPS on the same svc file isn't possible. You need to have an svc file that only talks HTTPS and one that talks HTTP. From my experience trying to get a specific WCF svc to respond in a mixed manner has been impossible.
You need make bindings with using HTTPS protocol + use SSL certificate on IIS
Related
I'm trying to self host two WCF services with the following url conventions:
https://service.servicehost.com/service
https://service-branch.servicehost.com/service
And I get this error:
Service cannot be started.
System.ServiceModel.AddressAlreadyInUseException: HTTP could not
register URL https://+:443/service/. Another application has already
registered this URL with HTTP.SYS. --->
I understand the error and I know how to work it around by changing the service's suffix, but it seems like the WCF self host doesn't support the host header feature like IIS does (since I see the + sign).
Is there any way I can make it happen?
I'm not sure this can be done for SelfHost/Http. With Net.Tcp you would have had to use PortSharing to make this happen.
Worst case you could potentially create a Routing Service that routes your requests to the correct service, where each is listening on a different port.
Also, take a look at the documentation for HostNameComparisonMode Enumeration. The docs for basicHttpBinding will show you how to use it.
I have been capturing traffic using Fiddler for some ASMX services that call other ASMX services. In this case, I have a simple WCF service calling those ASMX services. It won't capture any traffic. The only wrinkle is that it is using IIS not IISExpress (http://localhost/Interface12Service/Interface12Service.svc). How can I capture WCF traffic?
The Microsoft .NET Framework is hardcoded to bypass proxies for any request to http://localhost. To capture such requests in Fiddler or any other proxy, use
http://machinename:port/
or
http://localhost.fiddler:port/
as the target URL.
By default, Fiddler will not capture the traffic. If you want it to capture the traffic, change the client proxy base address to your machine name or to your IP (for instance: 127.0.0.1). This should do the trick. If not, try this.
It could just be that fiddler has difficulty picking up traffic from localhost
Try changing the address to http://localhost./Interface12Service/Interface12Service.svc
(Notice the dot after localhost.) This is a common hack for working with Fiddler.
Another possible issue is related to WCF client (this may also include other clients but i'm not sure).
The client can be configured not to use the machine default proxy, which makes the client/application bypass Fiddler capture.
For further reading: What is the purpose of usedefaultwebproxy in WCF.
If SSL is handled by a load balancer, do I still need to configure it in the WCF serviceCertificate node? My scenario is to use message level security. If someone can explain how load balancing with wcf and ssl works, that would be very nice.
WCF requires security tokens to be passed over a secure transport if the message itself is not signed/encrypted. Since traffic is HTTP between your Big-IP and your individual web servers, you need a way to have security tokens that you know are secured between the client and the Big-IP up front still be passed to your server farm. There's a couple ways to do that depending on what version of WCF you're using:
If you're using WCF 4.0 you can just create a custom binding and set the AllowInsecureTransport property on the built in SecurityBindingElement to signify that you don't care that the transport isn't secure.
If you're using WCF 3.5 you have to "lie" about security with a custom TransportSecurityBindingElement on the server side. You can read my old post about this here.
FWIW, they created a hotfix release for 3.5 SP1 that adds the AllowInsecureTransport to that version, but I don't know if your company will allow you to install custom hotfixes.
If you want to use message security then each message is encrypted and signed separately - there is no secure connection and load balancer behaves as with any other HTTP transport. Loadbalancer doesn't know about security and doesn't need certificate.
There are two gotchas:
All load balanced application servers hosting your WCF service must use the same certificate
You must ensure that your WCF binding doesn't use sessions (reliable, security) otherwise you will need load balancing algorithm with sticky sessions (all request for single session always routed to the same server)
It doesn't. Don't bother with this. You will be in a world of hurt. Just install the certs on each machine. We've recently been through this fiasco. WCF is not worth the effort it thinks it needs SSL but sees that it doesn't have it. Take a look at openrasta or something else if you want to do all your SSL on the loadbalancer. #microsoftfail
Let's say you've got a WCF service that is accessible via HTTP and HTTPS, but you want only certain methods to be available with HTTPS-- how can I check if the current request is HTTPS? Since HttpContext is empty, you can't simply check HttpContext.Current.Request.IsSecureConnection -- any other ideas? Thanks in advance.
Consider that WCF applications can also be hosted as a Windows service, with no ASP.NET at all, in which case there is no such thing as "secure" vs. "insecure." That is one reason why WCF does not attempt to make this information available.
One option would be to run the WCF service in ASP.NET Compatibility Mode, where you do have access to the HttpContext.Current instance.
My choice, however, would simply be to create a different, SSL-only service for the secure operations. I really think you'd want to do this anyway, so the contract is explicit; otherwise you're left doing runtime checks and clients may have no idea that the methods they're trying to use aren't allowed.
"Best practice" in a web service is to make these types of restrictions as explicit as possible, and having a separate service available only over SSL is by far the clearest means of describing your service's restrictions.
( Building on comment from #Aaronaught within answer by Matt Ellen... )
It looks like
OperationContext.Current.RequestContext.RequestMessage.Headers.To.Scheme
contains "http" or "https" among others (msdn).
HTTPS is served over a different port to HTTP. Assuming you know the ports, perhaps checking that would suffice.
How about:
var iwrc = WebOperationContext.Current.IncomingRequest;
var isHttps = iwrc.UriTemplateMatch.BaseUri.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase);
This is very easy, does not rely on port numbers and works just fine in a self-host WCF server (with no IIS in site sight).
Here is my scenario:
I have a proxy that actually has the SSL Cert installed and this sits in front of a load balanced web farm. Each IIS server does not have SSL so I can't use transport security via wsHttp binding. I have not investigated basicHttp because we want to provide SOAP 1.2 going forward w/ this solution. In addition to this, my network team won't allow any use of certs to encrypt at the message level. (this alone would solve my dilemma i'm sure)
My security group has a requirement that we use Forms Authentication (membership provider).
The final solution must allow SSL via the front proxy, yet some type of WCF binding to keep complexity encapsulated in a config file.
I was working with a custom binding that allowed for username/password sent via clear text, but when I try to connect via https i get the usual "http expected" uri error.
How can I use SSL via the proxy to connect securely from client app to web service, but not have SSL installed on IIS and leverage the WCF stack + forms authentication?
I'm not new to WCF, but this very custom setup seems to have me unsure if the requirements allow for any type "easy" solution.
Thank you in advance!
EDIT: I did finally get this working and decided to write a short blog post with complete source code required to write the custom binding.
I think this is similar to a problem many have had when wanting to provide WCF services over SSL when the actual service in IIS is behind an SSL-offloading device. In which case, the following two pages should help you out:
http://blog.hackedbrain.com/archive/2006/09/26/5281.aspx
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/87a254c8-e9d1-4d4c-8f62-54eae497423f/
Basically you need to lie to WCF and say that the service is secure, even though the traffic will be conducted over HTTP (between the service and the proxy).