12

We are building a RESTful API using WCF (currently .Net 3.5, but will be moving to .Net 4 soon). We have a functional framework in place, but it is currently unsecured. It will need to be accessible from .Net applications as well as iOS, Android, and web applications.

We would like to use an HMAC Authentication scheme as described here and here, but both examples seem to fall apart when describing how to validate the hash. The first example fails to describe the UserKeys object (hashtable?) and the second example is missing the GetUserKey methods on the client- and server-side.

Can anyone provide an explanation of how the "User Key"/token is generated/stored/retrieved/used in those examples or provide a better example (with source code, if possible) of how to use HMAC Authorization in a RESTful WCF service?

Edit: After more research, we determined that we needed more of an "Authorization" technique rather than an "Authentication" technique (semantics?). We implemented Basic Authorization and secured the API behind SSL. The Basic Authorization uses the same "Authorization" header from the web Request as the HMAC Authentication scheme, but passes a username:password string encoded in Base64 instead of a token. This allowed us to custom-validate a user against our database to determine if the user is licensed for and has appropriate security rights to access the desired API method.

We're certainly open to hearing other options on how to accomplish custom username/password validation and other methods for securing the API.

Snostorp
  • 544
  • 1
  • 8
  • 14
Steven King
  • 562
  • 1
  • 8
  • 13

2 Answers2

17

Retrieving the user key is just an implementation detail you can do any way you like but on the server it is often stored in a database along with the user name.

The basic approach is real simple.

  1. Somehow the server and the client exchange a shared key for the user to use. This can be done any way you like, including sending an old fashioned dead tree style letter. Quite often this is just the password the user entered.
  2. When the client wants to send a request he builds the complete request and then using the secret key computes a hash over the complete message body (and optionally some of the message headers if required)
  3. Next the client add the computed hash and his username to the message in one of the headers and sends it to the service.
  4. The service retrieves the username from the message header and searches the private keu for that user in its own database.
  5. Next he computes the hash over the message body (and selected headers) using the key to generate its hash.
  6. If the hash the client sends matches the hash the server computes the server knows the message was send by the real client and was not altered in any way.

Really the only tricky part is sharing a secret key with the user and keeping that secure. That is why some services allow for generation of shared keys with a limited life time so you can give the key to a third party to temporarily work on your behalf.

Maurice
  • 27,582
  • 5
  • 49
  • 62
  • This helped explain the *Authentication* method, which led to more research on our needs. We're still not clear on how the HMAC/key method would be used to *Authorize* a specific user's access to an API method any better than the Basic Authorization (username:password) method with SSL. – Steven King Dec 07 '11 at 21:07
  • The first step in any authorization scheme is authentication. After all how can you decide if another party is allowed to do something is you can't be sure of the identity of the other party. – Maurice Dec 07 '11 at 21:32
  • We added a class that inherits IHttpModule, checks the Authorization header, and creates a GenericPrincipal with a GenericIdentity (similar to what is described [here](http://blogs.x2line.com/al/articles/146.aspx)). It handles the 401/WWW-Authenticate handshaking. It allows the client to send a username/password and allows us to validate the user against our database. We don't have to exchange a secret key. Since it's wrapped in SSL, we get the secure connection and the custom Authorization we wanted. Is this approach appropriate for a RESTful API? – Steven King Dec 08 '11 at 19:23
  • Yes, its a perfectly good option used in lots of places. You are still exchanging a secret key though, it's called the password in this case :-) – Maurice Dec 08 '11 at 20:16
3

Implementation for HMAC we can find at

https://github.com/cuongle/WebAPI.Hmac

Venkat
  • 868
  • 1
  • 12
  • 21