5

I own a web application (single page application with Angular), that asks for some data through a set of REST APIs based on my server-side application (using Play Framework 2.2.1).

So basically, I'm not an expert in security and so I initially wanted to use a "tool" for implementing authentication easily. Thus I chose to make use of SecureSocial.

I customize it to fit my needs, but after reading some documentation about REST authentication scheme, I realized that I'm likely to be in a wrong way.

Why? Simply because it's based on a Session-token mechanism rather than a full stateless solution.

In short, the authentication workflow is:

  • The user logs in the web application through a traditional form (e-mail/password)
  • Server checks for the validity of the credentials (comparing BCrypt hashes for the password), and if valid, returns a cookie containing a kind of authentication token. This authentication token is also stored in server cache (Play configured to access a Memcached store), in order to be able to make some comparisons each time the user asks for a restricted (in term of visibility) functionality.

Pros of this solution:
..this works well for controlling access to RESTRICTED API.

Drawbacks:

  • This solution requires a datastore to store the authentication token on servers, in order to compare which the ones provide by client at each request attempt. Currently, I make use of Memcached.
  • Unable to restrict access to some small list of clients. Indeed, what if I want to restrict all REST API accesses to my application only? Surely needed for a kind of API key/API secret key to implement Authorization and not simply Authentication.
    For example, I strictly don't want to let external command lines or external web sites, accessing the APIs even if they succeeded the authentication step by providing some good credentials.
    Worst, they would have no difficulties to access some data that was initially public, meaning without authentication like for instance: taking a list of a precised set of data.
  • Seems to be very vulnerable to some known attacks if HTTPS transfers are not ensured.

I heard and read a lot about HTTP BASIC but it seems that it should be avoid: http://adrianotto.com/2013/02/why-http-basic-auth-is-bad/

Then I read about HMAC solution, as Amazon implements, and it seems a pretty good solution; OAuth1 sounding too complicated for simple cases I want.

Should I try to implement the HMAC solution?
Is the HMAC solution really compatible with a browser, meaning allowing user to call for several distinct operations without needing to authenticate each time?
Does it involve tokens exchanges in this case to do this trick?

I would be really happy if anyone could introduce me the concept of HMAC while dealing with a web application/ browser.
Indeed, I struggle to find some documentations about HMAC scheme coupled with browser.

Or perhaps, really trusting an Oauth Solution? ...

I'm meditating on the subject...

Mik378
  • 421
  • 4
  • 11
  • There's some useful info here: http://security.stackexchange.com/questions/49145/avoid-hitting-db-to-authenticate-a-user-on-every-request-in-stateless-web-app-ar – paj28 Feb 14 '14 at 11:43

3 Answers3

1

OAuth is useful when you have a three-parties scenario. This is when you have an authentication service that determines what the client can access on a resource service. In this scenario, the client connects to the resource by providing a token that proves that the authentication service has authorised the user to perform the operation. From the sound of it you don't really need OAuth.

If you're doing a server to server API (i.e. your service is accessed by another server and not by user's browser directly) then HTTP Basic is perfectly fine as long as your service is running over HTTPS (i.e. no unencrypted HTTP). HMAC won't really make this situation more secure. HMAC may be useful if you have to run your service over unencrypted HTTP as at the very least it prevents tampering by a MITM attacker, but given how easy it is to setup HTTPS nowadays, HMAC is much more complicated than anyone ever needs.

If you want an even better security than Basic, you can use Mutual TLS Authentication (a.k.a TLS client authentication). Mutual TLS is better than Basic because it uses asymmetric cryptography, which means that a compromise of either the client or the server doesn't compromise the security of the other key. In many circumstances, this benefit isn't really that important, but it might apply in your circumstance.

Lie Ryan
  • 31,089
  • 6
  • 68
  • 93
1

Don't roll your own auth, Json Web Token (JWT) can do what you want, it is simpler than oAuth and uses HMAC

user618509
  • 21
  • 2
0

I know it's a little late but saw it and thought I'd answer anyways. An HMAC is a (Keyed)-Hash Message Authentication Code. The way it works to secure an API, is as follows: you create an API token which is combined with a message and then hashed. This HMAC is then sent along with the username and the API call to be invoked to the API server:

https://apiserver.com/api/?mac=098f6bcd4621d373cade4e832627b4f6&user=leaustinwile&command=url_encode({json:"test"}).

The API backend then takes the message and computes the HMAC server side using the by finding the user's API token:

https://localhost/get_api_token/<user>

If the HMAC that was computed server side matches the HMAC sent with the message, then the API call is invoked because the message has been verified as authentic (from the correct origin in your instance).

leaustinwile
  • 366
  • 1
  • 8