I have a public WCF Service.
I have a WPF Desktop app & a silverlight app. My apps does not have any login requirements.
I want to make it difficult for another developer / website to make use of my service.
What's the best way to restrict access to my service? Use SSL and have the desktop / silverlight app store a token inside of it?
Yes, having a token / certificate be part of your installation is probably the most efficient way to make sure only computers with your own software will be able to access the service.
Also: do not publish the WSDL, e.g. turn off all metadata endpoints and "HTTP Get URL" and so on - don't publish your presence to everyone surfing around! ;-)
In addition, your app could also send some specific headers - although those are fairly easy to find and decipher.
And last but not least: you could come up with your own whacky binding, e.g. have some oddball combination, possibly your own serializer or message formatter. That's taking it quite far already, but it would definitely be possible to put up some hurdles there, too.
Related
This may be a very simple issue but is (I think) complex to explain so, please bear with me.
We have a WCF API (written in C#) on our server which attaches to third-party APIs (a sort of one-stop place, if you will). These use a mixture of OAuth and certificates for security. The idea is that we don't have to put (the third party) certificates / security on all of our servers, just the one.
Therefore, the plan is for an application on one server to call the API on this server which calls the third-party API. This seems to work for all but one third-party.
If I use the Visual Studio (2017) inbuilt WCF Test Client on our API, it works fine. If I try to use our API from another application (by adding a service reference) even on the same server it fails with the above message.
Our API does not (yet) use https.
The plan is for use to release our API to others so we can't share any certificates / logins with them - this is the underlying reason for our API.
I have done a lot of Googling about this and all of the answers seems to point to the certificate has to be on the calling application which would seem to defeat the object of our "catch all" API
I have probably not explained this very well - sorry. Maybe the issue could be summed up as "how do I stop the security being "passed down" to the calling application?"
Seems that the culprit was the Application Pool Identity that "Our" API was running under. I changed that and now everything works as I would expect it to :)
For the sake of argument, lets say that I've got a basicHttp WCF service. Besides implementing authentication (login/logout methods), what is stopping someone from just cracking open Visual Studio, adding a web reference to my website's service, and then playing playing around with my service? I'm not familiar with a method of stopping someone from doing this. The idea of someone downloading all of my Data/Operation contracts and then start playing around is keeping me up at night, and I like my sleep!
Discoverability is the driving factor behind Web Services and especially SOAs. The ability of anyone at all who can reach the service to pull up the WSDL, generate a proxy in Visual Studio (or some other tool), and start using the service is one of the main reasons to create a web service!
I suppose you could generate all the client proxies and then disable the mex endpoint, but that pretty much cripples WCF, and even then it's only security through obscurity.
If you don't want any miscreant to start hitting your web service then either don't use the basicHttpBinding (which is designed for the express purpose of immediate and anonymous consumption) or host the service on a private network which only trusted clients can reach.
Some form of authentication or encryption is the only thing that can prevent this. You have to distinguish between those you want give access to, and those you don't. Give the ones you want to have access the certificate necessary to do encryption, or the username and password.
Don't give anything to the others.
I am working on an app that has several clients - Desktop, Mobile Device, Web Portal. We're moving to an SOA kind of architecture and will be using WCF.
The WCF story is great when it comes to using netTcp+transport/message security+Windows authentication (or even UsernameToken and a custom UsernameValidator provider) on the Desktop and Web Portal side.
Where it totally breaks down is on the compact framework side...the subset of WCF it supports is so limiting. I was resigned to simply using basicHttp + Username/Password in the headers all over SSL, but it seems that you cannot add headers when on the compact framework stack (no OperationContextScope) - so that leaves me with including username/password as parameters for EVERY SINGLE operation method in the service.
Please tell me I am wrong and there is a better way.
Your best bet is going to be to expose a WCF end-point that conforms to the WS-Security standards.
You should then be able to use those standards for message based security (most likely using X.509). Here's the MSDN link to get started:
Messaging in the .NET Compact Framework
An alternative solution is to pass a ticket (read: guid).
The client logs in (sends username and password). A randomly generated ticket is generated (guid again), cached on the server, and sent back to the client. This ticket is then passed back and forth instead of the username and password.
Of course, all of that is assuming you don't just want to utilize session state.
But in other words: I've had the same problem you've had. It sucks. This is how I got around it a bit so it was usable.
Anyway, another good reference is the WCF Guidance for Mobile.
I'm rather new to the WCF/IIS/MS web stack corner of the world so I'm hoping for some help evaluating my design.
What I need is a system that presents a number of resources as URIs. Each resource is a WCF web service providing a number of read and write operations. I need to provide username/password security for different resources.
How I'm hoping to make this work is to have IIS handle the security using the normal devices it uses for everything else. Then uses URL rewriting to remap everything to a single web service that will provide the correct resource based on the rewritten query string.
Will this work?
Am I missing something?
Is there a better way to do this?
If you happen to known of a really good tutorial for the bits and peaces (like what file does the security settings go in?) I would appreciate links?
For now there will be only a handful (2 to 20) users so static config files would be preferred for that as along as it won't cause problems later.
As I said, I hardly known jack in this domain so I don't really known what I don't known.
A few links I have found (don't even known yet if I'm looking in the right direction)
Fundamentals of WCF Security (assumes a bit more familiarity than I have)
Improving Web Security: Scenarios and Implementation Guidance for WCF (really long, book length)
Yes this sounds sane. For authentication you want to use ASP.NET membership module it provides a generic security API which can use intergrated (windows user), web form login, even LiveID or some custom authentication. In my experience MSDN has proven a good resource, here's a hands on article.
For web http binding WCF provides Uri rewriting out of the box using WebGet attribute.
for SOAP, the end point URL is the same, so I assume you want RESTful endpoint. If so, you need Basic auth over https not WS-Security.
I am writing a Silverlight application that will be both reading and writing data to a serverside database via some WCF web services.
What is the best way to secure these web services?
My goal is to make sure the services can't be called by other applications and potentially spammed with requests to add items to the database. Only the Silverlight application needs to be able to access them.
Don is absolutely right that there's no foolproof way of making sure that the client is a Silverlight application.
However, I think you're asking more about the following: Can I make sure that only people I trust connect to the service.
The answer here is (basically) a yes, or at least we have standardized ways of doing this.
You're typically going to want to consider a couple of different approaches:
Transport level security. Has somebody tampered with the traffic? We use SSL for this.
Authentication. Am I talking to someone I trust? Here, we'll typically use one of the authentication mechanisms (Forms Auth, say). You can use Forms Authentication to secure both Silverlight (actually the page that Silverlight resides on) and the WCF services. Confusingly, SSL can be used (though rarely is because it's a pain in the neck) for authentication.
In general, you can't assume anything about the client. If you try to keep non-Silverlight apps from hitting your site, a malicious client can easily pretend to be a Silverlight app, and you're back to square one.
That is to say, this is not an effective way to secure a server. To secure your server, assume that any and all clients will hit your site, and start from there.
Edit:
Let me amend that to say that if you want to get into the world of mutual authentication, you can set up a PKI to manage certs, issue user certs for all your users, and then you know who your users are. Still, one of them might be malicious (and talented) and inject a cert into another client.