Friday 14 August 2015

OAuth2 - Why Authorization Code Grant Type exist at all?


If you have worked with or read about OAuth 2, you would have came across the fact that it has several "Grant Types".

The two of interest to me was:

  1. Authorization Code
  2. Implicit
When I was reading up on this topic, I couldn't understand why the Authorization Code grant type was necessary at all.

A quick recap the 2 grant types:

Authorization Code
Resource Owner (User) is prompted by the Resource Server (e.g. Facebook), asking

"XXX App wants to use your profile ..blah blah, do you allow it to do so??"

User confirms.  Resource Server redirects to the registered redirection link along with an "auth-code" in the param:

https://oauth2client.com/cb?code=AUTH_CODE_HERE

The client then needs to make an extra POST request to the Resource Server with the auth-code, clientId and the clientSecret to get the Access_Token.

The access token is the thing you attach to your subsequent requests to access the user resource.


Implicit
Up to a point, it is the same as Authorization Code described above.  However, instead of sending back an "auth-code", the resource server will immediately send back the access-token!  No extra step required!  The auth token is sent back as a hash fragment, NOT a request parameter (this point is important).

https://oauth2client.com/cb#token=ACCESS_TOKEN


Question
Both grant-type results in the ACCESS_TOKEN being sent back to the client after the Resource Owner agrees to share his resource.  So why do we need the authorization code grant type that has an extra step??


Answer
Hash Fragment is a browser thing.   It is not part of an http request, and when your request url looks like https://oauth2client.com/cb#token=ACCESS_TOKEN The #token=ACCESS_TOKEN is not sent to the server. 
 
This means it can't be read or intercepted by any servers (duh...its not sent!), so its secure without TLS.  I.e. its secured from Man in the Middle Attack.
However, it also means that this only works if the request is sent from the browser.  Good for your SPAs (Single Page Apps) and mobile apps.

We need to do something Web Servers and other non browser systems that requests for resource as well.

Since they Hash Fragments aren't sent to the server, information will have to be passed in the form of url parameters, but (unless the client is using TLS which is not a requirement for a OAuth2 redirect url) any server can read URL parameter, its part of the HTTP request which means its susceptible to a man in the middle attack.  So we cannot just attach the access token to it.  

So instead, the Resource Server sends back a redirect with an auth_code in it.
The idea behind the auth code is that ONLY a legitimate client (i.e. the one that holds the client secret .. kinda like a private key) will be able to exchange the code for a token.

To exchange the auth code, the client has to issue a POST request to the Resource Server.  The POST request has to include the auth_code, the clientId AND the clientSecret, and the response to this will be the ACCESS_TOKEN.

At this point you might be asking (... at least I was), why can the Resource Server send back an Access Token after the POST?  Why couldn't it just do that in the first request when it sent back the Auth_code??

The key here is that first was a redirect to client's page.  The client may or may not be HTTPS which means the response maybe in clear text!  The second was a request and response to the Resource Server which MUST be in HTTPS (which is why you can safely send your Client Secret and get the Access Token).




References:
https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified
http://stackoverflow.com/questions/13387698/why-is-there-an-authorization-code-flow-in-oauth2-when-implicit-flow-works-s