Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm working up an API for a REST service that I'm going to both be producing and consuming. I've spent the past few days trying to figure out how to handle authentication nicely, and think I've finally come up with something.

I'm coming up with this based on the following facts about the application stack:

  1. Client & Server are in .NET4 (Client part in Client Profile)
  2. Server exposes using WCF REST
  3. I really don't want to keep the user name and password in memory in the app

From 3, I wanted to use a form of token authentication, so that after the credentials are verified by the server, the client gets a token back to use throughout the rest of the app (this will allow me to do other things, such as timing out users, being able to move users seamlessly between the web and desktop versions, etc). After figuring out how to make the calls replay and tamper resistant, I've come up with the following:

  1. Before the client attempts to authenticate, it generates a Diffie-Hellman key pair using the ECDiffieHellmanCng class.
  2. It sends the public part of the key pair over the wire along with the user name and password (Over HTTPS of course).
  3. Server authenticates the username/password combination, if successful, it then does the following:
    1. Creates a unique session token
    2. Generates its own DH key pair, and calculate the shared secret from the public key provided by the client
    3. Makes note of the session token, the shared secret, the user, and the "last action" time (used for a rolling expiration window) in its database
    4. Returns the session token, its public DH key, and an authentication success message
  4. Client takes the DH key from the response, calculates the shared secret, and store both token and secret in memory.

From this point on, the session token/secret combination works like most other REST APIs, with the request being fingerprinted and timestamped, and then have some sort of HMAC generated. Whenever a client performs an action against the server, it checks the token/secret pair, and allows the action if it is valid and not expired, and updates the last action record in the session.

I don't see any obvious flaws, and is probably over-engineered for this, but I need to learn how to do this at some point. The HMAC prevents replay attacks, the DH negotiation helps prevent MITM attacks (I can't think of a workable attack off the top of my head between HMAC/DH).

Any holes anyone can poke in this?

share|improve this question
    
I don't see how generating the DH keys adds any security at all compared to simply using HTTPS everywhere and using plain old session cookie. When used properly, HTTPS already protects against man-in-the-middle and replay attacks. –  Lie Ryan Feb 19 '12 at 5:43

2 Answers 2

Rather than invent your own, you should consider reading the OpenAM API and borrowing it.

http://forgerock.com/openam.html

The OpenAM Wiki is particularly helpful

https://wikis.forgerock.org/confluence/display/openam/Home

You don't need to use their components. But if you use their API, you'll find that your life will be simpler in the long run.

share|improve this answer
    
Hmm, it doesn't look bad, one thing that's preventing me from using it in this case: We're a .Net shop. Plus, there's not a lot about using it with the WCF server side of things. The one non-spammy link I could find on google about it points to using WIF and WS-Federation. –  Matt Sieker Jul 14 '11 at 22:15
1  
@Matt Sieker: "You don't need to use their components". Please read about their API instead of inventing your own. –  S.Lott Jul 14 '11 at 22:16
    
Ah, I think I see what you mean, the requirements callback stuff. That is interesting, I might look into that more, if not for this project, for future ones. Instead of doing auth as one atomic chunk, break it up slightly, so the server can control what it needs from the client... –  Matt Sieker Jul 14 '11 at 22:25

I agree 100% with @S.Lott that you don't want to roll your own. I suggest looking at another alternative: the Windows Azure Access Control Service (ACS). ACS is costs money, but it is very cheap (10,000 transactions for $0.01) and a good deal of infrastructure is handled. WIF is leveraged on the client.

This is also a standards-based / claims-based solution - which is all the rage. Check out this article on using WCF and REST and ACS together.

If you are thinking of the future, this is also a mechanism that can grow with you - as you have mobile apps outside the firewall, partners, and so forth. Even if you don't want to use it since it adds a dependency outside of your firewall, you may want to check it out for ideas. Very slick.

Good luck! -Bill

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.