Monolith to Separate Services Help and Guidance - restful-architecture

I'm in the process of breaking a monolith into separate microservices. I already have a contact service - it stores Names, Email Addresses, Phone Numbers etc.
I want to create another service for organisations/businesses. These organisations have contacts so I'd like to use my existing Contact Service for this rather than recreating it all.
Can anyone advise on how I should structure this? I've thought of the following two ways.
1) Implement the Contact Service within the Org Service. So a user of the Org service is unaware the contact service is separate. This has the drawback that I need to recreate a load of endpoints in the Org service that simply (more or less) pass through to the contact service.
2) Let the user of these services create a contact through the contact service and then just create a way to 'attach' this contact to the organisation.
Is one of these preferable? Or is there another way I've not thought of?

Or is there another way I've not thought of?
3) Add the organisation to Contact domain model.
To me, both contacts and organisations naturally fall under the same "Contact" or "CRM" business domain.
Put another way, if you were to remove the Contacts Service, would the Organisation Service be able to do any useful work? If not, then this may be a signal that you should simply make Organisation a part of the Contact business domain.
This appears especially true as one of the options you outline the organisation service is just serving as a facade onto the contacts service. If there is no material difference between the Contact model in the Contact service and the representation of that model in the Organisation service, then they are effectively interchangeable and so should not be separated.

Related

How to best leverage ASP.Net Core Identity for a unique form of multitenancy in a Blazor Server app

I am in the process of designing a Blazor Server app that sits on top of a single MSSQL db.
I have done a fair amount of research and learning on the subject but I am still very new to Core Identity, so I need to better understand how it is meant to be used so that I can properly design the Authentication and Authorization pieces.
The app will consist of organizations. Users can belong to one or more organizations and within each organization, can belong to one of two roles: Coach or Student. But the Coach in one organization could be a student in another organization, and a student could be a student of more than one organization. But all of this should be tied to a single user account/login. If a user belongs to more than one organization, they will be presented with a screen to select which organization they want to access after completing the login process. Once they have selected the organization, their activity and access will be limited to that organization.
What would be the proper way to handle this type of arrangement? Since one user could be a coach in one org and a student in another, are roles the proper way to handle that? Or would those be claims where for example I would store the ID of the organization as the value of a claim called "Coach" or "Student"? Or some other way?
Initially, I was planning to only use Identity for Authentication and then use my own custom logic to perform Authorization based on these criteria, but I don't want to reinvent the wheel if I don't have to.
Thanks in advance for your guidance and recommendations on this.

Are there any approaches to use EF + DDD in the microservices architecture properly?

I've read a lot of topics about making ef core + ddd working together but they are only show an example where we have only one microservice. I stuck with solution about putting EF Core + DDD right where it's more than one. For example we have 1 database and 2 microservices (identity, schedule). In every service we have to keep own bounded context. Identity service only working with User, Role, ... tables... In opposite, schedule service working with User, Appointment, etc. Also, when we design a domain model we only using properties we need. So, in Appointment service for User entity I only need to use for example Id, NameDetails, Address, ContactInfo when in identity service I use Email, Password, etc. The question is: Should I use the different db context for each microservice? If yes, how I should handle migrations in that case?
Using one database for two or more microservices is a contradiction in itself. A microservice is supposed to be autonomous, meaning it should not share the same database with a different microservice.
If you need to reference a user-id for instance in two services, you would only store this id, whether it's an integer, a string or any other kind of key.
Your second database will not be able to validate the existence of that foreign key, since it doesn't know about the table where the Users are stored in.
You would want to create a single db-context for each service, that has it's own migrations and it's own database, when you really want to use microservices.
If you still want to use the same database to do that, you can create many DbContexts that actually point to the same database, but only define a set of entities.
In general there are different levels of domain-driven-design. You can do domain-driven-design without microservices and even without distributed systems. Keywords like Aggregates, Commands and Events, Distributed Systems are all part of domain-driven-design.
Some resources to read about domain-driven-design
https://stackoverflow.com/a/1222488/5397642
https://martinfowler.com/bliki/DDD_Aggregate.html
https://medium.com/withbetterco/using-aggregates-and-factories-in-domain-driven-design-34e0dff220c3
https://dev.to/designpuddle/apps--microservices--what-you-need-to-know-autonomy-and-the-challenges-you-will-face-39e1
I think that in this particular case User in Identity service isn't the same as User in Appointment service. I would make new Entity called, for example Person(with attributes such as NameDetails, Address, ContactInfo, DateOfBirth etc..) , in Appointment service and save it in separate database for that service (2 databases 2 services).

Fiware-Orion: Access control on a per subscription basis

I would like to know if the following scenario is possible:
A Fiware Orion Context Broker instance, to which different data providers connect to publish their data. For each data item (context), the particular data provider should be able to control which application or data consumer is allowed to subscribe to this context. Is this possible with Orion? How can this be done?
I've looked into the multitenant model, but I guess that is not the proper way to do this. Am I right? Are there any alternatives? You can protect the Orion instance with a PEP proxy, but I guess it does not allow access control on a per subscription basis.
Any hints would be highly appreciated.
The scenario that you propose can be implemented, if I understood correctly, with Steelskin PEP Proxy and the multitenant mechanism (but with some concerns).
In your scenario, your whole application would be a service (indicated in all transactions with the fiware-service), and each data-provider would own a dedicated subservice (indicated with the fiwareservicepath header). All the users (both administrator from the data-providers and final user and applications) would be users of that service. Using XACML, different permissions can be assigned to each possible action and user in different roles. E.g.: you can create a dataProvider role with full permissions under its subservice and a dataConsumer role that should be able just to subscribe and read.
This scenario has some problems, mainly concerning who creates the users and roles and assign roles to users. In order to use Steelskin, you have to map services to Keystone Domains and subservices to Keystone Projects; and users belong to the domain. It's the domain (service) administrator the one in charge of creating the users, so, in your case, data providers would not be able to create new users (and probably, even assigning them as subservice customers).
If you need an example on how to connect these pieces together to achieve this, take a look at:
https://github.com/telefonicaid/fiware-pep-steelskin/blob/master/keystoneInstallation.md
Hope it helps

Possible design strategies for login for multi-tenant cloud application?

I am working on a multi-tenant cloud application and considering using E-mail addresses/passwords for general login credentials. However, I may have the same user (same E-mail address) associated with multiple tenants based on the planned sales model for this application. For example, multiple departments in the same company might be separate tenants, or separate companies must be separate tenants. In either case the same user (with same E-mail address) might be a user of these different tenants.
What are possible design strategies for handling such situation?
One approach I am considering is separating creation and update of the user E-mail credentials from the tenants. In this approach a tenant could invite a user (by sending an E-mail) and the user can use the same login credentials for access to all tenants, merely switching between tenants as desired.
What I have typically seen in current web applications is that the user has to have separate E-mail addresses for each tenants, which seems a burden for the user.
Thanks.
Assuming your question is about the technical design (and not the user experience), this is a pretty straight forward solution. Create the users independently from the tenants, and allow for a many to many relationship that represents the "has access to" phrase.
Depending on your chosen backend, there are different manifestations of the design pattern:
RDBMS: Create a user table, tenant table and a user_has_access_to relationship table
Directory Server (LDAP): Place the users into a single OU within the directory, and create the tenants as group objects. The users could then have the memberOf attribute set for each tenant they are able to access.
The LDAP option above has the limitation of overloading the group entity. If you are comfortable enough with LDAP schema definitions, you could just as easily create a tenant object and add a hasAccessToTenant attribute to your user object. Taking this approach would allow you to use groups to represent actual user groups (as the object type was intended to be used).
A more advanced design option would include the creation of a "has access to" relationship between tenants. Adding this, along with the user to tenant relationship, would open up more advanced relationship modeling. For example: a tenant with departments or divisions, allowing users with permission to the top level tenant to automatically "have access to" the divisions.
Using the same credential across namespaces in multi-tenant applications is technically possible. For example, when a user logs in, the application can check across the namespaces and determine which all namespaces he belongs to. There is a possibility, the user may have different levels of authorizations against these namespaces. This is also implementable.
The real problem is the experience the application can offer to such users. They will require a special landing page which will allow them to chose between the namespaces. The chosen namespace should be made quasi-permanent during the session, that is, until the user logs out. ( I am trying to implement this in a new application on GAE/Python27 )
Other possibilities are restricting the user to a single namespace and asking the user to use different credentials against each namespace, which seems to be the prevailing practice.

RavenDb Authorization + SOA

The question I have is that of securing documents across services using RavenDb and the Authorization bundle:
I have an 'Account' service which is responsible for managing all things 'user'.
I have a 'Messaging' service which is responsible for all things 'messaging' i.e. wall posts, conversations etc.
To trace who did what in this service, when a new message is posted I create the message and two UserProxy objects (cut down User objects which only have UserId and UserName properties - these are stored as child objects on the WallPost doc so they aren't documents in their own right)
When a user posts something to another users wall i only want to allow:
delete/edit to the original poster, the recipient and admins
view to original poster, recipient, admins and all friends of the recipient
I also have a media service which is responsible for images/video, a MusicEvent service for all things music event - they all need to have a similar setup.
My question is this:
*should the account service store the master User with Roles and Permissions - when it is asked for a user it can send back a dto with the roles and permissions (could get chunky)
*should the Messaging Service maintain it's own copy of a User - with it's own set of roles and permissions?
first is simpler moving forward as it's centralised - but looks a bit dodgy to me
second is probably better but the issue comes when the AccountService changes the username - i can send an event to the esb and have all the relevant services pick it up and take care of the update - but that sounds complicated.
FTR - i'm swaying to option 2 - the non-centralised method.
Personally, I would think about introducing a third service - e.g. IT / Administration service that would be responsible for Roles and Permissions. Its strikes me that these are different business functions / capabilities to those described in Account or Messaging services. A service responsible for that type of functionality would decouple the security aspects of your services from the actual functional areas of Accounts and Messaging. Accounts could still remain the owner of Account information. The messaging service really only needs to identify the user and so using user id / username here is sufficient, unless it nees aditional user information to do its work (email address perhaps). Its ok to duplicate data in this instance, as long as Accounts remains the owner of information.
Ayende answered this for me quite nicely on his blog:
http://ayende.com/Blog/archive/2011/02/17/distributed-authorization-with-ravendb.aspx