OAuth within Public API and Microservices
While I have been experimenting the Azure API Management service, I came across the OAuth and the reading makes me re-think about how to secure Microservices. In this post, I am going to look at what the problem OAuth tries to solve, and its use in developing Public APIs and Microservices.
An application (resource server) stores resources owned and controlled by their owner (resource owner), when another application (client) tries to access those protected resources, resource server
- needs to authenticate the client and decide whether the client is allowed for the access
- needs to authenticate the resource owner and decide whether the resource owner is allowed for the access if the client on behalf of a resource owner
When it comes to authentication against the client and resource owner, how the resource server figures that out is a top secret, or otherwise it would be a huge security hole. A typical example of this kind of secret is the ASP.NET machine key and a data structure representing a user.
For the purpose of integration, the secret has to be shared, but how can it be shared securely?
To make it work, the secret is shared with the clients.
It works perfectly when the clients are fully trusted. For example, you work for a business and build front-end and backend applications for it. However, it is not acceptable when you plan to build an ecosystem or enable third-party applications to access your services.
OAuth addresses these issues by introducing an authorization layer and separating the role of the client from that of the resource owner.
An end-user (resource owner) can grant a printing service (client) access to her protected photos stored at a photo-sharing service (resource server), without sharing her username and password with the printing service. Instead, she authenticates directly with a server trusted by the photo-sharing service (authorization server), which issues the printing service delegation- specific credentials (access token).
At high level, the idea is that, instead of sharing the secret with clients, a new authorization server or such new role is introduced and it gives clients something that they pass to the resource server so that the authentication and authorisation can be worked out. This thing is called access token.
An Access Token represents an authorization (specific scopes and durations of access)
- issued to the client
- granted by the resource owner
- enforced by the resource server and authorization server
At the moment, tokens are mostly implemented as JSON Web Tokens, or JWTs. The information contained in JWTs are known as “claims”, or assertions.
JWT is a standard for safely passing claims in space constrained environments
If you want to learn more about JWT, Auth0 (you can think of it being the authorization server) offers a great mini book about it.
OAuth2 Example — Auth0
Auth0 is one of the leading providers that offer IDaaS. It offers two solutions at the moment, Client Authentication and API Authentication. I was struggling with understanding their use cases, but it becomes to make sense when I think about them from the Access Token’s perspective.
Client Authentication deals with a scenario where your application is a client on behalf a resource owner / customer. An access token is
- issued to an application you build and you have control (yep, your application is considered as a client rather than a resource server in this case, see the Roles)
- granted by the user
- enforced by Auth0
So that your application is able to use the access token to access resources (protected and hosted by Auth0, and owned by the user that grants the access token) by calling Auth0 API (like /userinfo).
API Authentication is designed for a use case where an access token is
- issued to a client, an application you do not have control (like a third party application)
- granted by the your application
- enforced by your application and Auth0
So that the client is able to use the access token to access resources (protected and hosted by your application, but not owned by a particular user) by calling your application’s API.
My previous experience was to build authentication logic in Public APIs so anyone who is not authenticated gets denied before the requests are forwarded to internal Microservices. It implies that internal Microservices do not worry about authentication and just trust the user’s identity passed in.
However, it looks like the logic can live within the Backend APIs (by having the access token passed around from Public APIs) as they need to know the resource owner the requests on behalf of anyway. It implies that the Public APIs do one less thing and become a more generic layer (meaning it could be reused in different scenarios just like Azure API Management service). All Public APIs do is to aggregate result from a set of internal Microservices, and perform generic operations such as rate limiting, caching, etc.