Microservices
5 min read

Understanding Microservices Authentication Services

The distributed setup of a microservice application not only increases the potential attack surface of your application but also adds a new layer of complexity to authentication, authorization and session management. Here, we explore the options available.

Authentication is the process of determining who a user is by, for example, asking them to provide a username and password or using multi-factor authentication. Once you know who the user is, you can check their account details to determine what they are authorized to access. Creating a session for an authenticated user preserves their current state and avoids them having to log in repeatedly in order to determine whether they are authorized to access a requested resource.

In a traditional, monolith-style web application, user authentication and session management are relatively simple: once authenticated, a session is created and stored on the server, where it can be accessed by any components that require it and used to inform and authorize subsequent requests. A session ID is sent to the client and used in all subsequent requests to the application to associate the request with the current session.

With a microservices-based application, services are designed to be self-contained and stateless so they can be deployed separately and scaled across multiple servers or containers. A different approach to authentication and session management is needed to ensure a scalable architecture.

Authenticating Microservices Requests

Rather than implement authentication logic in each microservice that makes up the application (which would mean replicating the same logic in every language or framework used by the application), most microservice-based applications include a dedicated authentication service. When a request is received, the authentication service is queried to ensure the user is authenticated and authorized before the request is processed by the relevant microservices.

Although it's possible to authenticate each request to an application by including the username and password in the HTTP header, basic authentication is not secure and risks exposing your users' data to attackers. HMAC authentication sends a hashed version of the password in the header for comparison against a plain text password stored on the server, making the server a security risk. By contrast, token-based authentication avoids sending credentials in the request header and provides a time-limited authentication mechanism.

With token-based authentication, if a request is received and the user is not currently authenticated, they are redirected to the authentication service where they enter their credentials. Once authenticated, an access token is generated and sent to the client which stores it as a cookie. The client then includes the token with each subsequent request to show that the user has already been authenticated. For each request, the access token is checked against the authentication service before being processed by the relevant service. Once the token has expired or been revoked, the user is no longer authenticated.

For security reasons, the access token should be as meaningless as possible to anyone who might intercept it; it should simply act as an identifier for the authentication service to check whether the request has come from an authorized user. This means session information cannot be included in the access token and must be stored somewhere else.

Distributed Session Management in Microservices

The traditional monolith approach to session management involves storing the user's session data on the server side. In a microservice application, the authentication service described above can provide a session ID for the client to include in subsequent requests. However, when services are distributed across multiple containers or servers, accessing server-side session data poses a potential problem.

One option is to set up a central data store that can be accessed by all the microservices. The data store must be secured and replicated for high availability to avoid a single point of failure. Alternatively, if instances of all necessary services are available on a single server, sticky sessions can be used to ensure all requests from the same user go to the same server. Session data is only stored on the selected server, where it is accessed as needed. However, this approach is vulnerable to the server failing or spikes in traffic forcing the load balancer to direct traffic to a different server, losing the user's session data. A further alternative is to replicate the session store across all servers. This can work well for smaller deployments, but there can be a significant impact on network bandwidth and ultimately performance when scaled across large numbers of servers.

Session Tokens with an API Gateway

An API gateway not only provides a single access point for your application's APIs - it can also provide authentication and session management. The authentication service described above can be implemented at the API gateway level to identify users and generate an access token for the client to include in future requests. On receiving a request, the API gateway checks the access token with the authentication service, which (if the user is still authenticated) returns a JSON web token (JWT) containing details of the user's session. The API gateway then forwards the request with the JWT to the relevant microservices, providing them with the user's session data. The response from the microservices is routed via the API gateway, which updates the session information as required and replaces the JWT with the access token shared with the client before the response.

This approach enables a stateless architecture, with session details included as part of each request. Limiting the JWT containing session details to communications upstream from the API gateway ensures that those details are protected by the security measures applied to the application and are less likely to be intercepted by a malicious actor. Furthermore, when a user logs out, their session can no longer be accessed from the server side, as the corresponding access token has been revoked.

OAuth and Authenticating with Third-Party Applications

It's increasingly common for third-party applications to request access to an application on behalf of a user, such as posting from an app to a social media account. Asking the user to enter their account login details into the third party application is bad practice, as it increases the potential attack surface. One alternative is to provide the user with an API key to use instead of their credentials, but an API key in a request is still open to interception by attackers. The preferred approach is to use OAuth, which uses tokens to identify requests from the user.

Authentication and Session Management with Kong

Applying authentication and session management at the API gateway ensures a consistent approach across your APIs. The Kong API gateway supports a range of plugins for authentication and session management, so you can choose the appropriate solution for your application.