We are planning on using OAuth2 / OpenID-connect for Authentication & Authorization and I'm looking at what services would be required. So far I've identified that I need at a minimum:
- An OpenID-connect authorization service, e.g. implemented using Identity Server
- Service(s) for registering and managing users
- Service(s) for registered and managing client applications
(My assumption here is that I'm better off having these as separate services rather than bundling all of these into some sort of authentication mini-monolith)
When servicing auth requests Identity Server will need to lookup the client id, and may also need to lookup user details. To me, it seems like the simplest solution would be a REST / HTTP request, e.g. something like this (where the password is contained in the body)
POST https://users.api/users/justinp/authenticate
It also seems to me that I want requests to this API to be authenticated, however, that creates a sort of circular dependency whereby the authorization service depends on the user service to fulfill requests, but the user service (and similarly the client app service) depend on the authorization service for authorization. This doesn't cause issues at runtime as the authorization server can, of course, generate its own valid authorization tokens, but the design still doesn't seem "quite right".
I can see how I could avoid this in various ways, e.g. by using CQRS / Event Sourcing – have the user and client app services push changes so that the authorization service can maintain its own internal list of users and clients, however this does up the complexity and I'm not entirely sure that it's necessary.
Is this "circular dependency" actually fine in this case, or is this architecture a bit wonky?
Best Answer
Before you do anything else, you should read this introductory article on HTTP authentication to get started.
Oath2 protocol flow is shown below as described in The OAuth 2.0 Authorization Framework:
All the resource services need to be able to validate the token. There are "many different and valid ways" to do OAuth2 but I would recommend using cryptographic signatures on the tokens. Then your resource servers can validate the token without reaching out to anything else. Revocation may be a concern however. I gather that initially the token specification was vendor specific but that there is now a standard around this.
As far as username recovery and password resetting goes, I would not consider that part of the authentication service. I would separate that out into it's own process and set of services that is independent of the authentication service.