Please note: Months ago I asked this question that received a truly amazing answer and introduction to OAuthv2. I’m now knee deep in the implementation of such a system and have similar (but notably different) concerns, and so this question is not a dupe of it. It’s more like a “Part 2” that, hopefully, documents the proper setup for a distributed OAuthv2-backed architecture. I think there’s value to that for future readers and onlookers.
Essentially I have the following architecture:
- A public RESTful web service provides CRUD operations on resources stored in other web services, databases, systems, etc.; and
- A web application sits “in front of” that REST service and provides a nice web/mobile GUI to those REST endpoints, allowing logged in users the chance to hit the endpoints through a user interface
- There is also a command-line tool that uses a HTTP client under the hood, so that if devops folk wish to hit the REST endpoint from their command-line, they can do so without having to write their own HTTP client or go through the UI (however they still need to authenticate/authorize themselves)
- Sitting “behind” this public REST service are other “backing” web services, some of which are backed by other things such as databases, LDAP directories, etc.
Since the REST service is public, other clients/customers can build their own HTTP clients and integrate with it, and so the auth option must be tolerant to that scenario as well.
Every component needs to be authenticated and authorized to do anything here. The CLI tool that devops folk use must be authenticated against the public REST service. Mobile/web users must be authed before they can even log in to the web app, and the web app must auth against the public REST service. The public REST service must auth against its backing services. Those services must auth against their backing resources/services/databases. Etc. I’m looking for an OAuthv2 solution for all of this.
One item that is not in the picture above, but very important, is that there will be a single OAuthv2 Auth Server used by all the server-side components (because I own everything except the client-side). Hence all services, databases, etc. will have access to the same auth server (and in reality, it is a cluster of HA Auth Servers).
Which grant types to use for each component?
My understanding of OAuthv2’s Client Credentials grant is for components updating their own metadata with the Auth Server, such as their client secrets or redirect URLs (yes???).
This means I really have to “map” each of those components to one of the other 3 grant types:
- Authorization code grant
- Implicit grant
- Resource Owner Password Credentials (hereafter ROPC)
After reading several | great OAuthv2 tutorials, it feels like the implicit grant is not applicable to any of the components here. It seems to be for when you have an unprotectable, client-side app that has no way of protecting access tokens. In my scenario, the only component that might qualify for this is the web app, however that will be on its own protected, trusted server that I control/own 100%.
So unless I’m misunderstanding something fundamental here, it seems I need to choose between Authorization Code grant and ROPC for all the following components/interactions:
- End user authentication against web app (to login to the web app itself)
- Web app authentication against public REST service
- CLI authentication against public REST service
- Custom built HTTP clients (not built by me, that is) authenticating against public REST service
- Public REST service authenticating against each backing (private) web service
- Private backing web services authenticating against their databases or external dependencies
Finally, my concerns!
I would imagine that the web app should use the Auth Code grant, but have concerns about that (see below). I would imagine the CLI tool and custom HTTP clients should use ROPC, but I have doubts about that as well. As far as the service-to-service and service-to-database use cases, I’m at a total loss. And so, finally, my questions:
- For each of the 6 use cases identified above, what is the proper grant type to use, and why?
- OK great, so that takes for of authentication. What about authorization?!? How does the auth server (or each component) assign roles/permissions to each access token?
- In each of the 6 uses cases that require the Auth Code grant, who hangs onto the refresh token (the client app, the auth server, the user agent)? How often will the end user need to authorize the client app (just one time ever, each working session/login)? It would be strange to force users to authorize the client app every single time they sit down to work in that system.