Search code examples
web-servicesoauthauthorizationoauth-2.0soa

OAuth 2: separating resource server and authorization server


The OAuth 2 spec leads me to believe that the "resource server" and "authorization server" do not necessarily have to be the same application but I'm struggling to figure out how this is actually implemented in practice.

As an example, suppose the following apps exist:

  • resource server
  • authorization server
  • web frontend
  • third-party client app

Scenario #1: Logging in to web frontend

  • user submits login form
  • web app POSTs credentials to auth server (grant_type=password) and receives an access_token
  • the web app stores the access_token in a session
  • upon each subsequent request:
    • GET resource(s) from the resource server (w/ access_token in Authorization header) and render it in the web frontend
    • if we get a 401 then log the user out (remove access_token from session)

Scenario #2: Authorizing third-party app

  • user requests authorization from auth service
  • allow/deny form is displayed
  • user is redirected back to client app with authorization code present
  • client app POSTs code to auth service (grant_type=authorization_code) and receives an access_token
  • client GETs resources from the resource server passing (w/ Auth header)

The part I'm having trouble understanding is how to authenticate the user before showing the allow/deny form in scenario #2. The user may be logged into the main web app but the auth service has no idea about that and would somehow need to authenticate the user again. Does the auth service need to support login/sessions as well?

I'm wondering if it might make more sense for the web app to be responsible for showing the allow/deny form for two reasons:

  1. it keeps all of the UI in a single app
  2. wouldn't force the user to resubmit his or her credentials if they are already logged in to the web app

Here's one possible alternative to scenario #2:

  • user requests authorization from web app
  • allow/deny form is displayed
  • web app POSTs to auth server creating a new grant, authorization code is returned
  • web app redirects to client app with authorization code present
  • client app POSTs code to auth service and receives access_token

What's the best way to handle this? Any general comments, advice, etc. would be awesome!

Thanks


Solution

  • Your alternate scenario is probably what you want to go with: if you really really want to separate your flows out, you could try something like this:

    1. user requests authorization from auth service on behalf of service with grant_type=code
    2. auth service realizes user is not logged in: redirects to web application with a request parameter asking the web server to send user back.
    3. web app stores request parameter, then asks for username/password
    4. web app POSTs credentials to auth server (grant_type=password) and receives an access_token.
    5. the web app stores the access_token in a session
    6. the web app generates a signed token capturing the user id and redirects back to auth service with signed token as request parameter
    7. the auth service parses signed token, extracts user id, displays allow/deny form
    8. user is redirected back to client app with authorization code present
    9. client app POSTs code to auth service (grant_type=authorization_code) and receives an access_token
    10. client GETs resources from the resource server passing (w/ Auth header)