When you design the services based on microservice architecture, typically authentication would be via federated authentication. It would have some oAuth service or STS (Security Token Service) which would grant token to the client.
In my scenario, their were bunch of microservices each nicely encapsulated in the Docker containers, each were portable and move from one host to another for high availability and redundancy. There was an API Gateway, which would be serving as the facade for these microservices and would do service discovery and bunch of other stuff.
Authentication was one work API Gateway did for us. It would received the jwt token from the client and check for its authenticity, scope and validity. Once all is good, it would forward call to microservice which is been designated for. Each microservice based on operation would call other microservices, collate the data and give back the response.
Now, the problem arise how to we authenticate call’s between Microservices? There were couple of options
Leave inter microservices call happen with authentication
Unfortunately, this wasn’t the choice for us, as these services where deployed on public shared infrastructure.
Let each service do token authentication with forwarded jwt token
This would be the option, but was overkill for us. Each microservice needs to have token authentication code. Plus, this would be anti-pattern as each microservice architecture, as cross cutting concerns like authentication is seeping in to the services. If there is change in jwt token data structure, changes needs to done in all microservices.
This was no go for us. We need some lightweight authentication just to validate if the call is from the our clan for microservices.
This lead to our third option, PKI based authentication.
Here, it’s simple, all microservice would run on HTTPS and would take client certificate for authentication. It would check client certificates against it own certificate and if it’s valid, it would let the call happen.
It was secure as all communication was over HTTPS and simpler to implement than JWT authentication
Here, how we did it.
We have microservices coded in python and nodejs. Caller where ASPNET dotnet core web apps and few data analytic services.
Simplistic Flask application is as below
Here, I have shown using the werkzeug server which good for development environment. On production you need to use some uwsgi server like gunicorn or uwsgi. Then this HTTPS code needs to be push to uwsgi service code.
For nodejs api services, here option to create the https server
The calling were dotnet applications. They would typically use some nuget package like RestSharp and code would be as following
CSharp (C#) Code
This way, I had secure my inter microservice communication using the certificates. Note, code which I have shown here is minimalist without the complexity of production environment, but good enough to guide the way.