5

In our project, we have several web services. Some of them are meant to be used only by the other services and the system administrator. We already have a global authentication system for users, this is not what I'm asking for here.

My question is: how should the authentication of communication between services be managed? What we need to prevent here is, basically, random people submitting queries/posts to this web services that are only meant to be used by the other services and not by people (except maybe the admin).

In case it helps, the web services are rails based.

Rory Alsop
  • 61,367
  • 12
  • 115
  • 320
bluehallu
  • 189
  • 1
  • 6
  • I would use a security certificate to authenticate the connection. – Ramhound Jul 09 '12 at 14:46
  • Can you provide more detail? To me, it sounds like what you're saying is that you already have role-based access control, but are interested in additional access control methods for the administrative API? – Mark Jul 09 '12 at 15:33
  • Yes with certificate definitely is OK. Simply it's encrypted and can be revoked and re-issued for specific ip address no problem. If not, that would mean that you would require another token, on top of the existing one - user-based, which is also global. So user without this internal random token, and not with their own one, will not be able to do any query on any of the web service, as any request without it would fail instantly. Also if it's only between servers, this can be protected with ip filtering as well, but this is not reliable method alone. – Andrew Smith Jul 09 '12 at 18:38
  • RESTful web service - how to authenticate requests from other services? https://stackoverflow.com/questions/6134082/restful-web-service-how-to-authenticate-requests-from-other-services – b4da May 24 '19 at 06:04

4 Answers4

3

If your system is relatively small and you're not too worried about man-in-the-middle attacks, then a pre-shared key is the simplest way to go. Think of it like a password that one server uses to recognize another. Ideally each server has its own password which is used to identify itself with others. If you need to, you can avoid disclosing the password while at the same time proving knowledge of it by using a challenge-response hashing mechanism.

If your system is large or adding and removing nodes happens often enough to make pre-shared keys difficult to maintain, then I'd recommend building your own PKI. This is simple enough to do with SSL certificates: just generate a central signing certificate and mark it (and it alone) as trusted to all of your servers, and issue each server/service its own certificate which it uses to identify itself with others. Use the subject field of the certificate to tie the certificate to the server/service, and of course sign each with your signing cert. SSL does provide for mutual authentication of both client and server for a single connection, so you can use completely off-the-shelf components for this. If necessary, you can include short expiration times and/or use revocation to enhance security if you're worried about keys falling in to the wrong hands.

tylerl
  • 82,225
  • 25
  • 148
  • 226
2

You are asking two separate questions here.

Programmatic access. The first question is: For web services that are only supposed to be exposed to other internal code, how should the programmatic clients be authenticated? My answer: I recommend using SSL with client certificates.

Here's how to do that, in more detail. The client should contact the service via a https URL. Each client should be provisioned with its own SSL client cert. The service should check that the client's cert is on a list of authorized clients, or else check that the client cert is signed by your internal CA (your choice).

In addition, for better security, you might consider running those internal-facing web services on a separate host that is firewalled off from the outside world, so nobody on the external Internet can open a connection to those internal web services.

Human access. The second question is: For web services that are only supposed to be exposed to internal system administrators, how should access be controlled? My answer: there are several approaches.

The simplest and probably the most pragmatic answer is to set up a separate account for each of your administrators, and use standard password-based authentication to limit access to those accounts. Generate a long, strong password for each admin account, and tell the admin not to share their password. Set up the web service to use SSL sitewide (only accessible via https, not via http), to prevent attackers from sniffing an admin's password if they happen to connect over an open Wifi connection. In this approach, the web services are still running on an externally-facing, Internet-connected host, but no one other than an admin should be able to log in to them.

A more secure approach is to put those web services on your internal network, and don't put them on an external-facing host. Firewall them off from the external Internet. If your admins want to log in while they are working remotely, they can VPN into your internal network. You will still want to create an account for each administrator on the web service and generate strong, long passwords for the admins.


For high-security installations, there are additional ways to provide even stronger security. Those mechanisms probably aren't necessary for the average internal web service, but if you are in an especially security-sensitive area, just let us know and we can provide you with additional controls.

D.W.
  • 98,420
  • 30
  • 267
  • 572
  • Hi. This is what I was looking for. We had a meeting where we discussed it, I was in for your same solution but others didn't like the idea of using ssl for "intern communication between servers", arguing that the performance impact would be huge and that it was "overkill". Finally we sort of agreed on just puting all this servers on a separate firewall protected network. While I really couldn't give arguments on why SSL was needed, I "have a feeling" that we're doing it wrong. Any ideas? Thanks again. – bluehallu Jul 18 '12 at 08:36
  • If it is firewalled off, only accessible via your internal network, and not reachable from the external Internet -- SSL probably isn't absolutely needed. (There are admittedly some risks, e.g., if you use wireless networks on your internal network and they aren't fully secured, but I'll assume you've secured any wireless networks inside your organization.) That said, SSL takes some risks off the table, and the performance overhead of SSL is a lot less than most think. I'd suspect your colleagues' intuition about performance overhead is not accurate. – D.W. Jul 18 '12 at 18:00
  • [The performance overhead of SSL is largely a myth](http://www.imperialviolet.org/2010/06/25/overclocking-ssl.html). For more, see [What are the pros and cons of site wide SSL (https)?](http://security.stackexchange.com/q/258/971), [How much overhead does SSL impose?](http://stackoverflow.com/q/548029/781723), [HTTP vs HTTPS performance](http://stackoverflow.com/q/149274/781723). But it is easy enough to test in your situation: turn on SSL (flip a bit in the configuration), then benchmark performance. I'd suggest doing the experiment, rather than just assuming it is too expensive. – D.W. Jul 18 '12 at 18:08
1

You question isn't very clear. It sounds one the one hand as if you are interested in intra service authentication, which is not what I assume you are trying to solve.

What we need to prevent here is, basically, random people submitting queries/posts to this web services that are only meant to be used by the other ones.

So if the objective is to only permit users who you can authenticate, I'd point your rails authentication provider to you "global authentication" system. I assume it has an LDAP interface so it should be rather simple to set that up.

Your authentication will also serve as your authorization since your objective was only to permit users who you can authenticate.

Marinus
  • 206
  • 1
  • 4
0

With a server-side, per-user, random key token, which is unknown to the user, but only to the webservices. This way, you got each execution in a specified context, like you have assigned a username to it. This can be passed via HTTP XML request, or in the Cookie header, or in the URL, depends on your requirements.

Simply each session would require pre-authentication of some sort, and use tokens across the services, so you dont have to login again.

This works same as user - server, the same way works server-server, like server has to login to the website, and then he can browse pages, in this case, web services.

Also when user logs in, he can be granted this token as well, so you can link front-end user with the back-end session.

Andrew Smith
  • 1
  • 1
  • 6
  • 19