Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with authentication in a micro-services architecture

I am currently reading a lot about microservices but still, I don't understand some parts. I made the following draw:

enter image description here

Each microservice has 2 accesses:

  • REST: For http uses
  • gRPC: For intra/background communication/exchanges

If I want to login I can just send an Http Request to my Authentication service. But what about if I want to access the Stuff service that needs you to be already connected?

Let say that the user wants to display the stuff available in the database STUFF, the service Stuff will first check if the "token" of the connected user is right, by exchanging with the Authentication service, and then return the stuff or a "login requires request".

So the thing I don't understand is, if each services that needs a client already connected needs to exchange with Authentication, then it will create a huge internet traffic in order to check each user request.. So I though about make one Authentication service per service, but since I should have only one Database, then it's the database that will slow the traffic?

Also, if I understand, each micro service should be on separate servers, not the same one?

I hope I am clear, don't hesitate to ask for more details !

Thanks in advance :)

Max

Edit 1

Based on @notionquest's answer:

So it should more looks like that right?

enter image description here

Also, based on Peter's comment, each service can implement its own middleware (JWT as mentioned) so the API Gateway is only a "pass-through". However, I don't feel like it could be a nice for me since each service make a token check for each internal exchange, doesn't it?

For the stuff, it's easy since it checks only 1 time the token. Now, let's say that, after the user got the stuff, he choose one and wanna buy it. Then the "Buying service" will call the stuff service in order the verify the price of the item, but... It will have to check the user token since the stuff is a "on authenticated access", so it means that "Buying" service and "Stuff" service both check the token, which add an extra check.

I though about an internal guaranteed access between services but is it worth it?

Also, maybe you said to implement the middleware for each service since they have a REST access, but the API Gateway would just destroy the idea of having REST access

like image 262
Emixam23 Avatar asked Apr 14 '18 21:04

Emixam23


People also ask

Which is a way to keep authenticated user state for stateless microservices?

JWT and stateless authenticationsJSON Web Tokens (JWT) are an open industry standard method for representing claims securely between two parties. It's a way to implement stateless authentication, that's when you don't need to persist the state of authenticated users (sessions) in any data store.

Which technique is used to secure microservices?

Implement security using a shared gateway Another approach to implement security for microservices is to use a shared component to implement security for individual microservices. This shared component can be an API gateway or a security gateway that will sit in front of the microservices layer.


Video Answer


2 Answers

There are multiple solutions available for this problem. One of the solution is API Gateway pattern.

  1. First request goes to API gateway
  2. API Gateway authenticates & authroizes the request
  3. Authentication is stored on cache database such as Redis, Memcache etc with expiry time on it
  4. Saved access token is returned to client
  5. Client can use the saved access token in the subsequent calls for the some time span (i.e. until the token is valid)
  6. Once the token is expired, the API gateway will authenticate and share the new token to client
  7. This solution will reduce the need to authenticate each request and improves the performance

API Gateway is the single entry point for all the services. So, you may not need separate cache for each service.

Refer the diagram in this page.

like image 149
notionquest Avatar answered Sep 28 '22 23:09

notionquest


Apart from @notionquest answer, there is another approach which does not involve having an API gateway;

You can share a SESSION_SECRET among all your services, so the only task of your Authentication Service is to validate username and password against the database and then encrypt this information using SESSION_SECRET and return a jwt token. All other services won't need to interact with Authentication Service but simply check if the jwt token is valid (can be decrypted) with the SESSION_SECRET.

You then have two other options;

  1. Store all user data you need in the token - this will increase the amount of data in transit from your client to the micro-services. This can be prohibitive depending on the size of this information

  2. You can store only the userId, and request additional data as needed per each micro service, which depending on how often/how big your data is will generate a problem as you described.

Note that you will not always be able to use this approach but depending on your specific scenario and requirements having this architecture in mind can be useful.

Also keep in mind that rotating the SESSION_SECRET can be tricky (although necessary for security reasons). AWS has just released a service called AWS Secrets Manager, so one idea to make things simple would be to have your micro-services periodically query a service like this for the current valid SESSION_SECRET instead of having this values hardcoded or as environment variables.

like image 20
Renato Gama Avatar answered Sep 28 '22 23:09

Renato Gama