Microservices is a fairly new, but already trending architectural term. Many big players like Netflix, Amazon or eBay built their portals or services based on this approach. The core attribute of microservices architecture is componentization – components are wrapped around business functionality, have to satisfy very targeted functions and are deployed to many independent environments. Thus, at the end, we have a distributed system with many components where authentication and authorization is a particular challenge.
Previously, in monolithic systems, we needed only one shared security barrier since components were conjoined. Security barrier could easily check caller’s identity against authentication service and then pass his credentials to other components. So, when more components were required to serve one request, only one call for user identity had to be done.
When applying the same principle of security barrier in the microservices world, we would need to replicate the approach for each particular microservice. This is highly inefficient since it requires multiple calls to get user identity once a request needs to access multiple components. And what more, multiplying of security barrier for every component is not just only ineffective, but also insecure.
Answering these challenges, a number of new industry standards have been introduced like Oauth2, OpenID and JWT. Implementation of these standards provides the ability to secure distributed microservices with the Single Sign-On (SSO) approach.
In the picture, you can see what the Oauth2 basic scenario looks like:
- The client requests the protected resource from the resource server.
- Authenticates by presenting the access token.
- The resource server validates the access token, and if valid, serves the request.
The Access token in basic Oauth2 scenario is opaque – so it has no “useful” information about the user. In other words, we are not able to get the user identity in component without having to again request an authentication service with user repository. So, this approach still doesn’t fix the problem with efficiency.
However, the solution for this particular challange has been already introduced with the concept of OpenID as an identity layer on top of Oauth2.
In the updated authorization flow, the Authorization Server, which is also called an OpenID Connect Provider, returns an ID Token (user identity) along with the Access token to the client (see picture below).
This data is then passed between the authorization flow parties and thus OAuth2 becomes identity aware.
As per OpenID implementation, a very popular and widely integrated one is JWT – JSON Web Tokens. It is an open industry standard and the basic term there is a “claim”, which can be a particular user attribute (uuid, email), timestamps, name/value pairs etc (check http://jwt.io).
So, in summary, the security approach described above introduces the concept of digital identity which can be elegantly used in our authentication and authorization scenarios. This approach has already become very popular and has been adopted by companies like Google, Facebook etc.
I have shared my code in Github (http://github.com/volodan/oauth). The example is built upon the latest Spring Framework technologies like Spring OAuth, Spring Security and Spring JWT and shows how we can bundle these new technologies together and build a simple authorization and resource server using OAuth2 with a focus on microservice-driven architecture.