The most notable difference in OAuth 2.0 is that the token that clients use to access protected resources is exchanged like a Cookie. Consider a typical flow for Cookie-based authentication:
- User submits a form to a resource with a user ID and password.
- On login, the site issues the browser a token via the
- The browser then sends that token with all future resource requests to all resources on that server using the
Cookieheader. The same-origin-policy tells the client the URI space that can receive the token.
Ignoring the mechanics of how the tokens are represented in HTTP, the OAuth 2.0 flow for browser-based clients is similar.
- User submits a form granting access to the client. This step may include login. This is similar to submitting a login form.
- The site issues the client (an app) a token (the Access Token) as part of the response body.
- The client then sends that token with all future resource requests using the
Authorizationheader. This is similar to sending a
Here is the difference. There is nothing in the OAuth 2.0 protocol to guide the client to say what URIs the client is allowed to send the access token to. The client is just supposed to know the URIs that the token is valid for, and ensure to not exchange the token with other servers. In OAuth 1.0 this is not an issue since, as instead of sending the raw access token, the client sends a signature of the token. The signature includes a nonce and a timestamp to prevent man-in-the-middle attacks. OAuth 2.0 does not have the same protection, just like Cookie-based authentication.
Eran argues that this is as bad as Cookie based authentication. True. However, in the interest of interoperability and ease of use, OAuth 2.0 is a step in the right direction.
If you are offering resources that support OAuth 2.0 and are concerned about replay or man-in-the-middle attacks, issue short-lived access tokens and use TLS. As far as I am aware, except for Yahoo!, no other OAuth 1.0 implementors offer short-lived access tokens or a way to renew expired access tokens. This needs to change. OAuth 2.0 specifies how to refresh access tokens when they expire.
There is another unintended consequence of OAuth 1.0. Since OAuth 1.0 resource requests include a nonce and a timestamp, resource developers tend to ignore basic concurrency control mechanisms in HTTP. Recently one developer argued with me that the signature protects his code from having to deal with duplicate
POSTs. But there are other ways to deal with that, and forcing signatures on clients is a bigger hammer than necessary.
PS: Thanks to JJ for asking me about this for his post on infoQ.
PPS: I do not claim to be a security expert. Caveat emptor!