1

I'm trying to develop my first REST web service and I have a big doubt for the login process to authorize users to do some actions that the anonymous users can't do. My idea is:

  1. users send to the service username and password (over https)
  2. the service check in the database if these are present
  3. if these are presents the service generate an encrypted token (that containsa time to live (10 minuts for example) and the user id) and send it back to user.
  4. in each user's request, the service check if the token is valid : if it is valid serve the request, re-generate a new token and send back to user else not authorize the action.

Now the question is:"is a good approach for security???" if not, please can you tell me an alternative?

Thanks a lot!

  • 1
    This has been asked a lot of times. Try searching for "[rest] authentication". I have a discussion on this issue on http://soabits.blogspot.dk/2014/02/api-authentication-considerations-and.html. – Jørn Wildt Feb 17 '15 at 15:05
  • Thanks I saw some questions but at today I have some doubts now I read the article. – Riccardo Mariani Feb 17 '15 at 15:10

2 Answers2

2

One concern I have is with the trust you place on the token. This token can be stolen, even if there is a TTL on it. A couple things you can do, authenticate with every request or map the token to the IP and port (aka the connection). This way it cannot be stolen. If that becomes too hard then just require the credentials with every request.

When authenticating the user make sure to salt your passwords int he DB. Please look up how to properly store passwords in a DB.

Do not have the password passed to you. The password should instead be used to encrypt a digest.

Another thing to consider is message authentication. Your approach does not implement MAC (message authentication). With MAC you ensure the message was not tampered with. While I agree that tampering with an SSL message is hard you never know when your client might be using non-SSL and then having a network appliance do the SSL for them. So the message might be visible for part of the way there.

So with all that taken into account this is what I recommend.

  1. Do not pass the password in the request.
  2. Implement a hashed digest that uses strong encryption like SHA-256.
  3. To create the digest hash the following: username, pw, some parts of the request if not all of it, and a NONCE (a number used once).
  4. The client can generate the NONCE them self, if they do it should be based on time, like a timestamp, so that you can verify that its a recent NONCE. Or you can send them a NONCE that you generate yourself in a 401 Authentication Required error code. Maybe the NONCE can be the token from your original post.
  5. For every request, the server will hash the same and verify that the digest value is the same.

What you will find is that other web services follow something similar to this but with different names. The points are this, don't pass the password in the message, use a digest for message and user authentication, use a NONCE so that the digest cannot be stolen and reused.

Jose Martinez
  • 11,452
  • 7
  • 53
  • 68
  • The digest hash I think that can be a very good solution to increase security! Thank you for the explanation!! – Riccardo Mariani Feb 17 '15 at 15:48
  • The first time I did msg digest I used the official HMAC (http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) protocol for generating the digests. Java has a method that does this for you. Other companies I worked for did not use HMAC. I do not know how prevalent it is. – Jose Martinez Feb 17 '15 at 16:16
2

login in REST web service

The answer is simple, you cannot do such a thing, because REST is stateless. REST is about machine to machine communication, so if you don't want to support 3rd party clients you most probable don't need REST. Ofc. you can implement it for your own ajax client, but it does not have huge benefits in that case especially not by a rarely visited site.

In you case you have to use https and send the username and password with every request in the header. You can have a server side cache of username+password -> userid+permissions, which can fasten this up. That's all. Forget the token, it is needed only by 3rd party clients.

inf3rno
  • 24,976
  • 11
  • 115
  • 197