tu4n
tu4n

Reputation: 4450

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

Hotel

Room

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?

Upvotes: 8

Views: 4496

Answers (1)

Jorge Córdoba
Jorge Córdoba

Reputation: 52123

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.

Upvotes: 11

Related Questions