Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API token authentication

Tags:

rest

c#

token

aes

api

I just started a development of my first REST API in .NET. Since it will be stateless I will use tokens for authentication:

Basic idea (System.Security.Cryptography):

  • AES for encryption + HMACSHA256 for integrity
  • token data will consist object with properties: username, date of issuing and timeout
  • database will hold username, hashed password and HMAC hash

Login:

  • check if credentials are valid (username, compare hashed password to db value)
  • if true, encrypt data object
  • use HMAC on generated token and store it to database
  • return token (without HMAC) to user (cookie/string)

Request to method which requires authentication:

  • user sends token with each request
  • token is decrypted
  • if it is expired, error
  • if not expired use HMAC and compare username + generated hash with db values
  • if db check valid, user is authenticated

The way I see it, this approach has following pros:

  • even if db is comprosmised, it does not contain actual token (hash cannot be reversed...)
  • even if attacker has token, he cannot increase expiration by updating fields since expiration date is in the token itself

Now firstly, I wonder if this is good approach at all.

Besides that I still didn't figure out, where to store AES and SHA256 keys on server (should i just hardcode them? If I put them into web.config or use machine key than I have a problem in case of load balanced servers,...).

And lastly where do I store AES IV vectors, since Crypto.CreateEncryptor requires it for decryption? Does it mean that users have to send token + IV with each request?

I hope this makes any sense and I thank you for answers in advance.

UPDATE:

Ok, now I did some more research and came down with this solution:

  • token will contain originally specified data (username, date of issuing and timeout)
  • token is generated with encrypt-then-mac (it includes AES encrypted data, IV vector + tag of these 2 values for authentication, generated with HMACSHA265)
  • token tag will be written to db
  • user will be authenticated if:
    • tag is valid (token authentication)
    • data can be decrypted
    • token has not expired yet
    • tag matches the one written in database
    • user is not blocked in database (token invalidation on demand)
  • keys will be stored in web.config separate section. Same keys will have to be on every server (per application of course)

I didn't use FormsAuthenticationTicket because in .NET there are following issues:

  • same keys are used for different purposes (machinekey for view states, resources and formauthtickets)
  • mac-then-encrypt, used by .NET is not considered as safe as encrypt-then-mac
  • no built in way to invalidate token before it is expired
like image 611
Pavle Gartner Avatar asked Mar 10 '13 11:03

Pavle Gartner


1 Answers

This is a follow up from the comment thread under the question.

You seem to be a bit confused as to what, exactly, OAuth is, so hopefully I can clarify it here.

OAuth is not a web service or something you consume. It is a protocol that describes the way that a site can authenticate a user against a service, without allowing the site to know what the user's credentials are. As a side benefit, most OAuth providers also have a web service to query the user's information, and permission to do so can be granted at the same time.

Typically, you are interested in implementing OAuth from the perspective of the site (eg, AcmeWidgets.com) so that a user can log in via Facebook or Google or something. However, you can also implement the service side (eg, where Facebook normally would be), and allow others to authenticate against YOU.

So, for example, let's say you have a web service to allow for third-party sites to provision Acme-brand Widgets for users. Your first third-party implementor is the popular MyBook.org. The flow would look something like this:

  1. Someone invites the User to use the "Acme Widgets" app on their MyBook profile.
  2. The user clicks on the button, which redirects to AcmeWidgets.com. The URL looks something like:

    http://acmewidgets.com/oauth/user?r=http%3A%2F%2Fmybook.org%2Foauth%2Fclient&appid=12345

  3. The user is asked if they want to allow MyBook to access their data and provision widgets.
  4. The user clicks Yes, whereupon Acme Widgets notes that the user has allowed it.
  5. The user is redirected back to MyBook, at a URL like this:

    http://mybook.org/oauth/client?token=ABCDEFG

  6. MyBook, on the server side, now takes that token, and places a web service call BACK to AcmeWidgets:

    http://acmewidgets.com/oauth/validate?token=ABCDEFG&appid=12345&appsecret=67890

  7. AcmeWidgets replies with the final authentication token identifying the user.
  8. Alternately, it fails, which means the user is trying to fake a token, or they denied permission or some other failure condition.
  9. MyBook, with the token, can now call AcmeWidgets APIs:

    http://acmewidgets.com/api/provision?appid=12345&token=ABC123&type=etc

This is all known as the OAuth dance. Note that there are a number of implementation defined things here, like URLs, the means of encoding the various tokens, whether tokens can expire or be revoked, etc.

Hopefully that clears everything up for you!

like image 174
Mike Caron Avatar answered Oct 18 '22 15:10

Mike Caron