I am currently building microservices based system on java Spring Cloud. Some microservices use PostgreSQL and some of them MongoDB. REST and JMS is used for communication. The plan is to use SSO and OAuth2 for authentication
The challenge I am facing is that authorisation have to be done on domain object/entity level. It means some kind of ACL (Access Control List) is needed. The best practice for this kind of architecture is to avoid something like this and have coarse grained security probably on application/service layer level in every microservice but unfortunately it is not possible.
My final idea is to use Spring Security ACL and have the ACL tables in shared database between all microservices. The database would be accessed only by Spring infrastructure or through Spring api. The DB schema looks stable and unlikely will change. In this case I would simply break the rule about sharing db between microservices.
I was considering different kinds of distributed solutions but left them:
- One microservice with ACL and accessing it using rest - The problem is too many http calls and performance degradation. I would have to extend Spring Security ACL to replace db access by rest calls
- ACL in every microservice for its own entities - Sounds quite reasonable but imagine a case having some read models of entities synchronised to some other microservices or same entity that exists in different bounded contexts (different microservices). ACLs can become really unmanageable and can be source of errors.
- One microservice with ACL tables that are synchronised to other microservices as a read model. The problem is that there is no support in Spring Security ACL for MongoDB. I have seen some custom solutions on github and yes it is doable. But...when creating a new entity I have to create record in the microservice that owns ACL and then it is asynchronously synchronised as a read model to microservice owning the entity. It does not sound as a easy solution
- Choose some URL based access control on API gateway. But I would have to modify Spring Security ACL somehow. The API gateway would have to know too much about other services. Granularity of access control is bound to REST api granularity. Maybe I can not imagine all the consequences and other problems that would this approach bring
- Finally the solution with shared db that I mentioned is my favorite. Actually it was the first one I have disqualified because it is “shared” database. But after going through possibilities it seemed to me that this is the only one that would work. There is some more additional complexity in case I would like to use some kind of caching because distributed cache would be needed.
I would really use some advice and opinions how to approach the architecture because this is really tricky and a lot of things can go wrong here.
Many thanks,
Lukas