2

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?

3
  • A few questions: It seems like you are rolling your own solution here. Why are you not using standard authentication mechanisms? Why does the authentication mechanism need user details?
    – JimmyJames
    Commented May 16, 2017 at 21:24
  • @JimmyJames So the authentication mechanism needs the users username and hashed password to authenticate the user, or their external sso subject_id if external authentication is configured. It also needs the email address (for "forgot my password" workflow) as well as things like their role (to include in the generated JWT) etc... What do you mean by "standard authentication mechanism"? Part of my confusion is that I'm not entirely clear what the standard authentication solution looks like in a microservices architecture.
    – Justin
    Commented May 16, 2017 at 23:14
  • "Rather then a authentication mini-monolith" - hype driven development, right there. Why not put every class into its own microservice? Just imagine the flexibility! (Irony off)
    – marstato
    Commented Apr 13, 2018 at 6:21

2 Answers 2

1

Allow lookup of a User ID or token from the User service without authentication. The User ID is not privileged information (in a properly designed system). If exposing the User ID makes you uncomfortable, then generate a one-time user token that expires after a short period of time.

Once the User ID is authenticated (either by the User service or a separate Authentication service that is provided a User ID/token and authentication factors), all of the services should work as expected (including the User service).

1

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:

 +--------+                               +---------------+
 |        |--(A)- Authorization Request ->|   Resource    |
 |        |                               |     Owner     |
 |        |<-(B)-- Authorization Grant ---|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(C)-- Authorization Grant -->| Authorization |
 | Client |                               |     Server    |
 |        |<-(D)----- Access Token -------|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(E)----- Access Token ------>|    Resource   |
 |        |                               |     Server    |
 |        |<-(F)--- Protected Resource ---|               |
 +--------+                               +---------------+

                 Figure 1: Abstract Protocol Flow

The abstract OAuth 2.0 flow illustrated in Figure 1 describes the
interaction between the four roles and includes the following steps:

(A)  The client requests authorization from the resource owner.

(B)  The client receives an authorization grant, which is a
     credential representing the resource owner's authorization

(C)  The client requests an access token by authenticating with the
     authorization server and presenting the authorization grant.

(D)  The authorization server authenticates the client and validates
     the authorization grant, and if valid, issues an access token.

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.

4
  • To add: you cannot implement the entire OAuth2 spec without configuring a woefully insecure system. RFC 6749 is sloppily composed, but it accurately reflects the spec's design process. You have to read RFC 6749 for understanding but then carve out your own security flow with supplements (RFC6750, for instance) In my opinion, you should not expect to be able to refer to 6749 for implementation guidance Commented May 17, 2017 at 13:53
  • @K.AlanBates I'm no expert on Oauth2, I simply cobbled together the references. If you have any edits, feel free to add them. I'm not sure whether Oauth2 is really a requirement here. The token thing seems pretty straightforward. I was surprised that signatures are optional on the tokens.
    – JimmyJames
    Commented May 17, 2017 at 13:59
  • Why are there three steps (or six, depending on how you count)? Is it so that a symmetric key can be negotiated using PKI? Also, doesn't this answer just beg the original question? Commented May 17, 2017 at 14:16
  • @RobertHarvey I've added a abridged version of the description of the first four steps as described in the RFC. The last interaction is simply getting the resource post authentication. As far as begging the question, I'm not sure what you mean. I'm trying to demonstrate that there is no need to implement a (direct) dependency between the resource service and the authentication service at all, much less in a circular fashion.
    – JimmyJames
    Commented May 17, 2017 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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