Authentication and Authorization in Microservices
When I started working on the transformation project from Monolith to Microservice, the challenge I faced was how to authenticate users on a distributed microservice framework.All you need to know is who the users are, right?And do your micro service know what they can do?
When you make a request to a Micro Service, how does microservice know who you are and whether to accept this request or not. In this post we will try to understand how to authenticate and authorize requests we make to Micro Services.
First let’s try to understand what is Authentication and Authorization.
Authentication is all about who you are. Consider Online shopping scenario, that if you wish to see all orders, then the micro service should know who you are.By default, HTTP requests do not include any information on who made the request. Pass User information in HTTP headers. This may be Username and password or API Key or Bearer token.
Authorization is about what you are allowed to do. Consider online shopping scenario, imagine there is an endpoint allows order to be refunded. If I am a customer, then I am not allowed to access this endpoint, I can’t issue refund myself. Only employees from application are allowed to do this. Authorization is not only based on who I am and also based on what action I am performing.
Defense in Depth (DID):
DID principle states that don’t rely on single security mechanism. Apply multiple layers of protection.
That way, if one of layers is get breached and hackers still doesn’t have access to your data. Let’s see some to security technique should be part of our overall strategy.
Multiple layers of Security
a Encryption in transit
b. Use industry standard algorithms to encrypt data.
c. Encryption at REST
d. Encrypted disks.
a. Not all endpoints are publically accessible.
b. Use IP whitelisting, firewalls and VNets.
c. Should accept requests which are coming from API Gateways.
a. Regular security reviews and audits
b. Scan for known vulnerabilities.
Authenticating End Users
Let’s look at how typical login works in non-micro service application and then will see problems with this approach when it is used with micro services.
End User Login process
User visits login page and type in username and password. The credentials that entered will be sent to server in HTTP request. This is why encryption in transit is important. Hence we will use HTTPS to prevent someone else intersecting the credentials. We can pass these in HTTP headers called Authorization header. This process is known as Basic Access Authentication. This Authorization header is also used for authentication.
On server side, we have to validate login credentials which is usually done by going to database and checking credentials are correct. And Passwords are stored as hashes using cryptographic techniques. If credentials are valid then web server issues cookie and stored in client browser and sent every subsequent HTTP request back to the server. Then server validates is cookie related to active user session. There are some problems with this authentication when it comes to micro services. Let’s see what those are.
Problems with Basic Authentication
This method works fine when you have request from browser to web server and single database. What if we want to design mobile application? How we can authenticate user? Redirecting to User database or maintaining another replica database?
Using an Authorization Server
Authorization server which is also called identity server — please refer below image. In this approach client application presents credentials to authorization server and it returns access token to them if those credentials are valid and client presents that token (Bearer token) in HTTP headers to micro service. The micro service able to validate token by checking with identity server is token really issued by identity server. This can be done by public key cryptography and discover the identity who is making call. The same can done to another micro services. The protocols underly this process are OAuth 2.0 and OpenID Connect.
OAuth 2.0 is concerned about delegated authorization. In other words rather than micro service is authorizing caller it delegates responsibility to another service which is called authorization server. But OAuth 2.0 doesn’t tell about who the user is.
OpenID Connect built on OAUth 2.0 and introduces concept of Identity token, which gives standard way of transmitting information of identity of users. This information is passed around JSON web token or JWT. JWT stores various useful information about the caller and it is cryptographically signed, so the content can’t be modified by the client before it is being passed to the microservices. One of the benefit using this service is we can use Third Party identity services for ex you can let user login using Facebook, Google.
Authentication Between MicroServices
We have seen when frontend application such as website or mobile application talk to the API gateways or Back end for front end (BFF), we can authenticate who is making request by passing bearer token which was issued by Identity Server and passing that token to BFF. But BFF can make call to different micro services. And it is possible a micro service can call another micro service. So what authentication can used for micro service to micro service communication? There are number of approaches to take. One approach is network security we can have virtual network for all micro service hosted servers. Here BFF accepts requests from public and validates with Identity Server and calls microservice, these microservices are accessed only inside virtual network.
With this approach we might thinking we don’t need any authentication between microservices. But if you remember Defense in Depth principle we should avoid relying on single security layer. Basically requests between micro services should authenticate themselves. One way to do is using API keys, this way each request from microservice to microservice could include secret key in http header whenever makes call, and the receiving microservice can look up the key in the list of authorized callers. Though this approach works, but it introduces additional list of secret keys to be maintained. And alternate to this approach is using client certificates in https requests. This way you need install certificate in client micro service and it presents certificate as part of HTTP handshake. But problem with this approach is configuring and maintaining certificates are overhead task.
Fortunately we can use Authorization server authentication as we seen before between microservice to microservice communications. Microservices or BFF can also request access token from identity server and pass those tokens in their requests to other Microservices. This approach will be consistent approach we can use throughout an application. Please refer below image.
Authorization in Microservices
Authorization is something what you are allowed to do. Let’s consider online shopping example — refer below image. We have catalog microservice maintains catalog of items. It has endpoint GetProducts, this endpoint is called whenever user demands for products. For this no matter whether user is logged in or not. Here request is flown from shopping website through shopping BFF. BFF passes request to endpoint since everyone has access to GetProducts. Catalog microservice also has endpoints called Post/Put Products. These endpoints can be only accessed by employees/Admin of Online shopping website. Customers shouldn’t access these endpoints. Here Authorization comes into picture. Here one advantage using BFF is, we can have separate BFF for customers and it exposes only Get end points from catalog microservice. For Admin/Employees of Online Shopping website we can separate BFF called Marketing BFF, here all PUT and POST endpoints are exposed. Only Admin can access these endpoints.
We explored the challenges authenticating and authorizing microservices each other. We saw Authentication is about who you are and authorization is about what you are allowed to do. Always adopt Defense in depth strategy for securing microservices, don’t rely on single security layer.