Microservice architecture - organizing user preferences across multiple microservices - microservices

Let's say we have a 'User' microservice and a 'Notification' microservice.
'User' microservice is responsible for creating and updating a user - this is where UserId is being generated.
Initially, 'User' model itself has a long list of properties related to different domains, one of them is a 'Notification' domain, for example properties like:
Email
CellPhone#
AllowEmail
AllowSMS
What would be the best approach to organize update of Notification related User properties across these two microservices?
Keep Update of these Notification related properties within the 'User' microservice, use it as an upstream to a 'Notification' microservice. When a user is created in a 'User' microservice and its Notification properties are set - propagate them via a service bus to 'Notification' microservice, where its User entity will contain just those properties of interest.
Do not allow update of Notification related properties in 'User' microservice, but expose them through a 'Notification' microservice because they are related to a 'Notification' domain.
If we take 'Notification' microservice out of the picture and just look at the 'User' microservice as is, would it be acceptable to split its responsibilities between multiple micro services where each will be responsible for update of a certain group of properties, and only one will be in charge of creating a User?
For example 'User Core' microservice and 'User Recipient' microservice?
Thanks!

Related

Keycloack users

I need advice how to manage users. In my app I will have few roles like admin, manager, worker, customer. I'm wondering where to hold the users data. For example I need manager to be in relation with app entity, so I must create separate entities in my app other than keycloak. I'm thinking about creating entities on my app layer that are contain keycloak ids, but now I don't know, if entities on app layer should contain data like email or hold them only on keycloak level? Or maybe is this wrong aproach and I shouldn't create users on my app and only manage them by keycloak? Some advice would be appreciated

Workflow involving multiple micro services

I would like to hear your opinion on how you would solve following problem.
The setting:
Multi tenant platform for several products in the cloud
Tenants are able to subscribe different sets of combinable products
Product domain separated Microservices in a kubernetes environment
internal jwt token authentication
Rest APIs and GraphQL API composition, Message Bus
The Problem:
A workflow combining two products should automatically add data to a specific referenced object in one product from another when a state change happens. This should only execute if enabled and if both products are subscribed. When the later condition is not met, the object reference would not exists so maybe its irrelevant to consider. Enabling may be done per Object or globally.
Example: (Pseudo classes prefixed by Domain Name)
Printer.Document: {
id,
printedAt,
documentDisposingData: {
}
}
Disposing.DisposingOrder: {
id,
documentId, //optional
disposingData: {
}
status
}
In the product 'Printing' I'm able to create a 'Document'. In the product 'Disposing' I'm able to create a 'DisposingOrder' independent or with a one way reference to the Document by an optional attribute. The 'DisposingOrder' would have enough attributes to work without the need for a 'Document'.
The documentDisposingData is a placeholder for several attributes of the 'Document' that can be set manually. The additional workflow should set these attributes when the DisposingOrder state is switched to 'done' for example. This state change is currently a result of a user interaction, but it might also be event triggered. The data structure is not the same so it needs to be mapped.
Tackling the problem I currently think about three different solutions, which all have backdrafts in some way:
Let the 'DisposingOrder' sends a event which is processed by the
'Printer' domain service which updates the 'Document'.
The Event from 1. is processed by a third service which updates
the 'Document' by rest
The 'Disposing' services knows the 'Printing' service and can
directly call it to manipulate the 'Document'
My thoughts:
The 'Printing' domain needs to know the usecase and if the workflow is enabled. Where should the configuration reside to decide if the information should be applied? Authentication is not considerable.
A new services specific for a usecase is needed which needs authentication to use the 'Printing' API. The 'Printing' domain does not need to know 'Disposing' at all. it could store the configuration
No loose micro service coupling. Authentication required if state changes by event.
What do you think?

Spring Security: Creating multiple entry point for securing different rest controllers

I'm exploring the Spring framework, and in particular I am working on a Cinema Management Application that will be connected to a React.JS SPA (Single Page Application).
The problem is the following. On my database I do have three different tables representing three different types of users, namely Admin, Customer, and Cinema_Employee.
For each type of user, I created a #RestController with a list of RequestMethods that a particular user is able to perform:
"/admin"
"/customer"
"/employee"
What I am trying to achieve now, it's to secure each endpoint offering three different login pages that will handle the authentication the respective type of user.
How can I set up three AuthenticationManager that handle different Authentication objects within a SecurityConfig class given these requirements, and most importantly, how can I override the Authorisation mindful that each user once has logged in, will have access only to the respective endpoint?
I looked carefully at other examples online, and most of them are radical different, following a pattern where the database has another additional 'Authorities' table aside the 'user' one that stores the credential. In my case this solution cannot be applied, not only because the whole design would become redundant, but also because the name of the table where the application will perform the authentication check against, explicitly imply the authorisation that a given user has inside the system.
Your design sounds strange to me.
A user should have a role, e.g. Admin, Customer, Employee and based on the user's role he gets access to methods or not. Have a look at role based access control concepts. For Spring Security there is for example this tutorial:
https://www.baeldung.com/role-and-privilege-for-spring-security-registration

Separate access in one app with keycloak

I have the following setup - the Spring SAAS REST service, which allows different companies to manage different events. And there is a rest client (a mobile app) also, shipped separately for each company.
I want to use keycloak for security stuff, and I have a question of how to separate one company from another.
I need companyA to not be able to access companyB event, and also need different roles within the company - some can create events, some can only read it.
First I thought each company will have own realm created in keycloak, but I learned that realm actually specified in the spring boot REST service parameters like
keycloak.realm=demo-realm
Which means it is only one realm per REST application. And I don't want to configure REST service instance per client. I only want one REST rule them all.
Am I trying to use something which really doesn't fit my use case?
Will it be right way to have a keycloack Group configured for each company, and make a logic in such a way that users of one group won't have access to what is created by other group. But then it actually feels wrong, since as I understand group are supposed to be used in a different way - to have admin group and user group, etc, segregating users "vertically" by "privileges", and not "horizontally".
Can you please suggest a right approach for this problem?
I would implement a custom protocol mapper which loads extra user permissions for your application and stores them in a token. This way, you use a single realm and if there are more companies in the future it scales well. Here you've got an example of how to implement it.
Basically, the otherClaims field of the access token is a JSON field that allows a map of properties to be set. You could add a field here such as:
userAccessibleCompanyIds: [1,3,4]
How to load the company ids for the concrete user? You can access your application database from the mapper or get them using the REST API.
Then in your application you need to have a control of what the user accesses. What I do is decode the token and see if the user request suits. If not, return a 403 response.

Authenticating dependent models in Spring / Grails

I have a domain model structure laid out in GORM like:
User -< Company -< Product
These are mapped to RESTFUL routes similar to:
/company/1
/company/1/product/6
The currently logged in user is available in controllers as user.
Given this ownership structure, I want to ensure:
a user can't access company they don't own
and can't access products that are not associated with companies they own.
Is there a general, declarative approach to handling this Spring (or in Grails)? The obvious approach of:
if (product.company.user != user) throw new Exception()
...in an application controller seems brittle, especially as the object hierarchy expands.

Resources