I've spent more than 10 days trying to understand the Authorization Code Flow for a web application where I'm supposed to implement OpenID Connect for a single sign on. It feels that there is a lot of conflicting information out there and I still haven't gotten a clear picture of everything.

  • In many places people mention that the access_token ends up to the browser.
  • In a book I'm reading it mentions that the access_token should never be delivered to the end user. It specifically mentions that it should always go from server-to-server (with client_id and client_secret).

This makes me think that the flow should be something like this

Browser                       Resource Server                  Auth Server
   | --------- GET /authorize ------------------------------------> |
   | <-------- 302 myapp/callback?code=100 ------------------------ |
   | -- GET myapp/callback?code=100 -> |
   |                                   | --- GET /access_token --> |
   |                                   | <-- token --------------- |
   | <- 200 OK ----------------------- |

So in this case the token ends up at the Resource Server which is also the confidential client. But then what is the point of a token anyway if the server itself is holding it to access itself?

It would make more sense if the token was at the browser so that the user can fire requests to the server directly. I feel even more puzzled now since it seems that the server would need to do some cross reference between session cookies and access_tokens, so that it knows that John is now asking for resource x.

Is my thinking correct?

  • I'm not expert enough to post an answer, but I feel like the token goes to the browser, and the browser attaches it to whatever calls it makes to the server. That would match how SAML works. There is debate about whether the end user should be able to view the contents of the token, or if there are privacy concerns. I know SAML allows the token to be encrypted from the authority using the public key of the recipient server. Maybe that's what that comment you saw is about? – Mike Ounsworth Nov 17 '19 at 1:48

The browser gets the authorization code, but not the access token.

For the OAuth2.0 Authorization Code Grant, suppose you're logged in to an app that will manage files you have stored on Google Drive.

  • The files are the resource
  • You're the end-user/resource owner
  • The app is hosted on the client server
  • Google is the authorization server

On the app you click 'Add files from Google Drive'. You get redirected to Google with the following information:

  • response_type ('code')
  • client_id
  • redirect_uri (hosted by client)
  • scope (in this case 'https://www.googleapis.com/auth/drive'; this is not a url, it just uniquely identifies the resource)
  • state (a random string to prevent CSRF)

You're now on the Google login page, where it will show the message 'App would like to access your files on Google Drive'. Upon successfully authenticating, you'll be redirected to the client at 'redirect_uri', with the following information:

  • code
  • state (from the previous step)

Now the client makes a request to Google. Note that the user agent for this request is the client's server, not the end-user's web browser. The client sends the following information:

  • grant_type ('authorization_code')
  • code (from the previous step)
  • redirect_uri (must be identical to the previous one)
  • client_id
  • credentials (the authorization server MAY accept any form of client authentication meeting its security requirements [1])

The authorization server returns:

  • access_token
  • refresh_token (optional)

Now you're back on the page you were originally on. On the backend, the client server can access all your files on Google Drive using the access_token it just received plus it's own id and credentials. This access token never reaches your browser.

The OpenID Connect Auhtorization Code Flow uses a similar method, but instead of granting access to a resource, it allows the client to authenticate the end-user (think 'Sign in with Google').


[1] https://tools.ietf.org/html/rfc6749#section-4.1

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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