1
votes

I have been reading about OAuth 2.0 Authorization Code flow to protect APIs in microservices architectures but I dont understand how an access token issued by the Auth Server is supposed to protect an API hosted in another server.

Is that same access token also kept in the API and when the client tries to access it with the access token issued by the Auth Server, the API checks if contains it? If so, does that mean that the access token is sent both to client and the protected API in the authentication process?

I hope to have explained my problem well. Thanks in advance.

2

2 Answers

3
votes

Anunay gave a pretty good analogy of how JWTs work at a high level as portable, trustable identifier, but since OAuth supports more than just JWT authentication it might warrant sharing a bit more detail.

Token introspection

In your question you rightly assumed that tokens need some way of being trusted, and that one such way would be to store the token in a private database and do a lookup whenever a token is presented to determine its validity. You would absolutely be able to instrument a valid OAuth server using a method like this by issuing the token using whatever form you wish and writing an introspection endpoint that performs the lookup. The OAuth spec is intentionally abstract so that the functional behavior of token introspection can take many forms.

One of the reasons for this level of abstraction is because while storing the tokens for direct lookup might be easy, it means that you have to store copies of these tokens in some form in a private database for comparison. This storage would in turn make you a honeypot for bad actors, both internally and externally, who would seek to impersonate your users en-masse. It's for this reason that many implementations of OAuth prefer to issue and validate tokens using public/private key encryption instead of direct lookups. This process is very much like the one Anunay described in his comment in that it issues tokens that are signed with a private key and verified with a public one. With this process, you no longer need to keep everyone's token in a private database, and instead simply need to secure private and public keys that are used to sign and verify tokens respectively.

JSON Web Tokens (JWTs) and reducing number of introspection calls

Anunay's response specifically referred to a common token structure that is generated using public/private key encryption and issued to users, JSON Web Tokens. These tokens are structured in such a way that they include the user information a backend service might need like the User ID, email address, and sometimes more, in a raw format that is directly readable to the backend API. In addition to this raw information however, JWTs include a duplicate copy of the data, but this duplicate copy is private-key encrypted. In order to trust a JWT token, all you have to do is use the public key and ensure that the private-key encoded payload is verifiable by applying the public key to the raw payload. Since public keys rarely change, many backend services cache the keys used for verification and elect not to do a token introspection on the issuing server since they already can verify the payload. This is how you'd optimize throughput on backend services that are protected via OAuth.

Since public keys can only be used to verify payloads and not produce them, these public keys are often broadcast by the servers that issued the tokens allowing anyone to "trust" the tokens it issues if they so choose. To learn more about this process, I'd recommend you research OpenID Connect.

2
votes

Access token can be understood as an passport that government issue to the citizen based on proof of identity. When you take it to another country, they look at the document and trust it because they trust the country and you because you are the holder of that document with you details. They trust the fact that passport cannot be fiddled with and allow you entry

Now for access token, in very simple terms, authorization server verifies the user. Once verified it issues the user a JWT token (Access Token). This token is signed with private key. It has your details and is encoded along with signature. Now you can take this token to any third party who has got the public key and trust the authorization server. Now when you share the access token with this third party, it use public key to verify the token and check for expiry. If valid it allows you in. So API doesn't really need to talk to auth server or keep any details about the token. All its needs is a public key to decode the token.

Now there are two important things. One if you ever let loose your access token, or some one who is not intended to get hold of your token gets it, he can do what ever he wants and auth server will not be able to do much. However as you see this approach reduces the chattiness of the systems specially microservices.

So to address this we limit the expiry of access token. Like passport, it comes with expiry. Shorter you keep it,user have to go and get the token refreshed with auth server. Every time he does so, auth server gets a change to verify creds and other details. If they do not match access token will not be refreshed.