Deep Dive into Authentication in Microservices
Zexuan Luo / Shirui Zhao
December 23, 2022
What Is Authentication Service
Authentication is verifying a user's identity to grant a user access and the necessary permissions to use the system. The service that provides this function is the authentication service. In a traditional monolithic software application, all of this happens within the same application, but the system is composed of multiple services in a microservices architecture. Each microservice has its own tasks in such an architecture, so implementing the authorization and authentication process separately for each microservice doesn’t work completely.
This article will compare traditional authentication and microservice authentication. And demonstrate the changes in authentication brought by the changes in the architecture. Finally, we will analyze the various authentication services in the microservice architecture and their pros and cons in their implementations.
Authentication Service in Traditional Architecture
In the early days, when enterprises developed services, all functions were implemented in the same application. We call this model "monolithic" to distinguish it from the current, more mainstream "microservice" architecture.
A monolithic application consists of a single indivisible unit. It is usually developed independently by separate lines of business and combined into the same environment when deployed. All of these are tightly integrated to provide all functionalities in one unit. This unit has all the resources needed. The advantage of a monolithic application is that it is easy to deploy and iterate. It is suitable for more independent companies with fewer business lines.
As the businesses developed by enterprises become increasingly complex, we will find that single services can no longer meet the needs of rapid iteration in real life. We need to split this giant system and ensure that the calls between existing functions can be carried out normally. To solve this problem, ESB (Enterprise Service Bus) came into being.
The "enterprise service bus" is a pipeline connecting various enterprise services. The existence of ESB is to integrate different services with different protocols. ESB provides services such as translation and routing of client requests, so different services can be interconnected easily. As you can tell from the name, its concept borrows from the communication model in the principle of computer composition - bus, all systems that need to communicate with external systems connect to ESB. You can use the existing system to build a new loosely coupled heterogeneous distributed system.
ESB has translated and routed requests so that different services can communicate with each other. The traditional ESB service invocation method is that every time the caller must be first routed through the central ESB to the service.
Monolithic Architecture
User authentication and session management are relatively simple: authentication and authorization happen in the same application, usually using a session-based authentication scheme. Once authenticated, a session is created and stored on the server. Any component can access and use it to notify and authorize subsequent requests. The session ID is sent to the client and used to associate all the subsequent requests with the current session.
ESB Architecture
Under the ESB architecture, all processes between services are processed through the ESB bus. Since the ESB architecture derives from the monolithic architecture, the authentication method has not changed compared with the monolith architecture.
Authentication Service in Microservice Architecture
Migrating from a monolithic architecture to a microservice architecture has many advantages. Still, as a distributed architecture, the microservice architecture has a larger attack surface, making it more challenging to share user context. Therefore, different authentication services are needed under the microservice architecture to respond to more significant security challenges.
We can divide authentication services under the microservice architecture into the following three categories:
- Implement authentication on each microservice
- Implement authentication through an authentication service
- Implement authentication through the API gateway
Each approach has its own specific advantages and disadvantages.
Implement Authentication on Each Microservice
Since each microservice is split from the monolithic architecture, a natural transition to implement authentication is for each microservice to implement it on its own.
Each microservice must implement its independent security guarantees, enforced at each entry point. This approach empowers microservices teams to make autonomous decisions about implementing their security solutions. However, this approach has several disadvantages:
- Security logic needs to be implemented repeatedly in each microservice. This leads to code duplication between services.
- It distracts the development team from focusing on their main service.
- Each microservice depends on user authentication data that it does not own.
- Difficult to maintain and monitor.
One option to better this solution is to use a shared authentication library loaded on each microservice. This will prevent code duplication, and the development team will only focus on their business domain. However, there are still shortcomings that this improvement cannot solve. Because the shared authentication library still needs to have corresponding user identity data, it is also necessary to ensure that each microservice uses the exact version of the authentication library. The shared authentication library is more like the result of poor service splitting.
Advantages: fast implementation, strong independence
Disadvantages: code duplication between services; violation of the single responsibility principle; difficulty in maintaining
Implement Authentication Through an Authentication Service
Since it is difficult for each microservice to implement authentication by itself, and using a shared authentication library violates the original intention of microservice splitting, can the shared authentication library be upgraded to a dedicated authentication service?
In this case, all access is controlled by the same service, similar to the authentication function in a monolithic application. Each business service must send a separate authorization request to the access control module when performing an operation.
However, this approach slows down the service and increases the interconnection between services. And each microservice will rely on this "single” authentication service. It is vulnerable to a single point of failure and chain reaction that causes additional damage.
Advantages: Each microservice has a single responsibility, and authentication is centralized
Disadvantages: Single point of failure; increased request latency
Implement Authentication Through the API Gateway
When migrating to a microservices architecture, one question that needs to be answered is how the microservices communicate with each other. The ESB mentioned above is one approach, but more commonly, an API gateway is employed. The API gateway is a single entry point for all requests. It provides flexibility by acting as a central interface for consuming these microservices. A microservice that needs to access other microservices (from now on, we will refer to it as a "client" to distinguish it from the microservice it accesses) does not have direct access to services, but sends the request to the API gateway responsible for routing the client to the upstream service.
Because all requests must go through the API gateway first, it's an excellent candidate for enforcing authentication issues. It reduces latency (calls to authentication services) and ensures that the authentication process is consistent across the application.
For example, using APISIX's jwt-auth plugin, we can implement authentication on the gateway.
- We must configure several user identity information (name, key, etc.) on APISIX.
- According to the given user's key, initiate a signature request to APISIX to get the user's JWT token.
- Then, when the client needs to access an upstream service, it brings the JWT token, and APISIX acts as the API gateway to proxy this access.
- Finally, APISIX will complete the authentication operation using the JWT token.
Of course, everything has advantages and disadvantages, and no technology is complete without drawbacks. Using an API gateway to complete authentication still has some problems. Solving this problem on the gateway is less secure than completing authentication within each microservice. For example, if the API gateway is compromised, it will expose all microservices behind it. But the risk is relative. Compared with the single authentication service, the problem of using an API gateway is mild.
Advantages: Effective protection of backend microservices; microservices do not need to handle any authentication logic
Disadvantage: Single point of failure
Summary
In different scenarios, we will need different authentication schemes. In a monolithic application, authentication happens within the same application, and the server saves all sessions. In the era of microservices, monolithic applications have evolved into distributed services, and the traditional authentication methods do not apply. In the microservice architecture, we have three authentication methods to choose from:
- Implement authentication on each microservice
- Implement authentication through an authentication service
- Implement authentication through the API gateway
Each option has its own advantages and disadvantages, which need to be analysed in detail according to the circumstances.