Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microservices: Centralized Authorization vs Authorization in each service

Let's say I have a Microservices system built with an API Gateway.

Every request after coming through the Gateway have to be pre-authenticated by an Authentication Service (The Firewall pattern)

Firewall Pattern

But how about Authorization? For instance, I have 3 models and 3 services according to them in a Hotel Management system:

User

  • each user can have many hotels

Hotel

  • a hotel is owned by a single user (owner)
  • each hotel can have many employees (also a user)
  • a hotel can have many rooms
  • for the sake of simplicity let's pretend that an employee have the same rights as the owner over a hotel

Room

  • a room can only belong to a single hotel
  • owner and employees can only edit rooms in hotels that they owned/employed at

An example request to edit a room Y, after being authenticated it will have a verified claim that state something like 'I am user X'.

To know whether X has the right to edit over Y I have to make requests to Hotel Service asking "Does Y's Hotel associated with (owned by/employing) X?".

The question is: Where do I make these requests?
Have the Gateway ask the Hotel Service before forwarding client request to Room Service, or let the Room Service ask the Hotel Service by itself. When to choose one over another ? What's the benefit ?


Also, this modeling seems kinda wrong to me. All these relations laying around Microservices just make my system really complicated. As it grows it becomes harder for me to visualize the workflow between services. Is there a solution to this problem? A centralized relationship service that utilizes graph database like Neo4j perhaps?

like image 579
rocketspacer Avatar asked Dec 05 '16 03:12

rocketspacer


People also ask

Should each microservice handle its own authorization?

Central dependency—authentication and authorization logic must be handled separately by each microservice. You could use the same code in all microservices, but this requires that all microservices support a specific language or framework.

Which authentication technique is best for microservices?

OAuth 2.0, for example, offers an industry-standard protocol for authorizing users across distributed systems. Within the context of microservices, OAuth 2.0's client credential flow allows for secure server-to-server communication between an API client and an API server.

Which is the best suited authorization mechanism in microservices?

Use RBAC and ABAC to Control End-User Actions In a similar way, it's also a best practice to use role-based access control (RBAC) to control what end users are authorized to do in the cluster, based on their job function. Much more than a best practice, RBAC is the foundation of authorization at the application level.

How authorization works in microservices?

Authorization implementation by each microservices Every API request made to service from end user or other microservice is first evaluated by go authorization middleware and request is passed to microservice implementation only when access is allowed by authorization policy.


1 Answers

TL;DR; Your problem is that you're basically translating your data model into services. That is wrong, that's not how you model a microservice architecture. It is not about the data model, is about the functionality. (I'm basing this on the way you framed the question, you don't talk about functionality and responsibilities, you talk about relationships).

I'm going to answer quickly the first part of your question as I think your problem is actually on your modeling.

About authentication and authorization

The question is: Where do I make these requests? Have the Gateway ask the Hotel Service before forwarding client request to Room Service, or let the Room Service ask the Hotel Service by itself. When to choose one over another ? What's the benefit ?

First of, on your model, the Room Service is the one with enough context to actually authorize the request. The gateway doesn't have (nor should it have) enough information to judge (the gateway should NOT understand anything about rooms or hotels or anything, its job is to forward requests, not to interpret them).

Secondly, even though you can have the room service ask the hotel for authorization, it is better if the room service does it by himself or calling another service whose responsibility is to provide authorization (i.e. an authorization service).

But most importantly, this microservice architecture doesn't make a lot of sense (as you've described it) and that is why the whole model is strange to work with.


Why the model is wrong

The reason this modeling seems wrong is because it is.

The problem with the term "micro"service, is that people tend to focus on the "micro" part and forget about the "service" part. There're different views on what a microservice is, but a service is something that can be invoked on its own and provides a value that is shared across several clients of that service.

Your Room Service makes no sense. You're basically translating your data model into services. A Hotel has rooms, so you define a Hotel Service and a Room Service. That is NOT what microservices are about...

Without knowing your particular user requirements it is difficult to judge but my gut feeling is you probably do not need a microservice architecture in here. Just because that's the latest trend you don't need to solve every single problem with it.

If your operations are stuff like "Register a new room, add photos to a room, remove photos from a room, book a room, etc", you're better off just having a backend service with a simple API that allows you to do all those simple kind of operations. Honestly, a Hotel Management System does not seem like the right kind of application to build using a microservice architecture. This feels more like a traditional MVC model to be honest.

If I had to come up with a use case for a room microservice I'd say you may want to have a room service that is aware of ALL the rooms on all the hotels. Rooms can be registered by a hotel, edited and changed. Anyone can get a list of all the rooms available, filtered by date available, filtered by number of beds, etc.

Note we now have two or three possible clients: - Your frontrend for administering hotels. - Your frontrend for seaching rooms. - Someone's elses frontrend for your room service to search rooms??.

Note also we've changed the system, from a Hotel Management System to a system that can be used to query different hotels for free rooms... useful, but a completely different kind of user needs.

So now your service actually make sense... and then pieces will start failing into place.

Because now you have anonymous users (or users from outside the system) it doesn't make sense to go to the hotel service anymore (after all a user doesn't need to administer a hotel any longer) so why would the hotel service know?.

Now, how are you going to handle the users of your system? Would there be different users for each microservice? Or is there going to be a single user that is shared across all microservices? Probably the latter, so that hints at another service for authentication (or you can use oauth2 if that fits your model which is exactly that, a service that authenticates people).

How are you going to manage your permissions (your authorization), do you want a central configuration for authorization or would each microservice have its own config? If it is the former, then you probably want another service that provides authorization to each microservice.

like image 188
Jorge Córdoba Avatar answered Sep 22 '22 19:09

Jorge Córdoba