You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am currently attempting to build a multitenant system where a single sign in page (provided by a SPA), is able to perform all the functions of ASP.Net Core Identity. I have some customs requirements due to providing functionality for a mobile app and desktop app. For context, the application is a shift scheduling and time management system.
Requirements:
Users need to be able to access multiple tenants after login, selecting the individual tenant preferably. (Default if there is only one tenant connected to the account.
A subset of users must be able to self register (administrative users) and a subset must be invited to use the system.
Invited Users need to able to switch between tenants if necessary. (think of switching between employers if a user has two roles at two different firms which both use the system for managing their shifts)
Certain DbContext operations need to check for data across multiple tenants. (think comparing shifts assigned to users and user availability)
Data Model context:
Users are connected to Tenants (Organisations) via an Employee class. Organisations create an Employee class. Users have a One to Many relationship with Employees.
Below is some of the implemented code:
publicclassClockworkDbContext:IdentityDbContext<ApplicationUser,ApplicationRole,Guid>,IMultiTenantDbContext{publicDbSet<Organisation>Organisations{get;set;}publicDbSet<Employee>Employees{get;set;}protectedoverridevoidOnModelCreating(ModelBuildermodelBuilder){//Create the Entities firstbase.OnModelCreating(modelBuilder);//Enforcing MultitenancymodelBuilder.ConfigureMultiTenant();}publicoverrideintSaveChanges(boolacceptAllChangesOnSuccess){this.EnforceMultiTenant();returnbase.SaveChanges(acceptAllChangesOnSuccess);}publicoverrideasyncTask<int>SaveChangesAsync(boolacceptAllChangesOnSuccess,CancellationTokencancellationToken=default(CancellationToken)){this.EnforceMultiTenant();returnawaitbase.SaveChangesAsync(acceptAllChangesOnSuccess,cancellationToken);}publicITenantInfo?TenantInfo{get;}publicTenantMismatchModeTenantMismatchMode{get;}publicTenantNotSetModeTenantNotSetMode{get;}}
publicclassApplicationUser:IdentityUser<Guid>{publicDateOnlyDateOfBirth{get;set;}//Verification of birthday for identity that this is the correct user.}
At present, when I generate the ApplicationUser class, it is always bound to an Organisation via the Multitenancy system. What I would like to know is what I am doing wrong. I have looked through the past issues, but very few go into details about implementing Multitenancy in this fashion.
The text was updated successfully, but these errors were encountered:
Hi, thank you for providing god details. If users are one-to-many with a tenant then in most cases effectively it is many-to-many because of course a tenant can have multiple users.
In this case (if you think it makes sense for you) I actually recommend not using Finbuckle's multitenant Identity context but instead use a normal Identity context with a Tenant entity added in and a many-to-many relationship with user. It simplifies some things such as allowing login by email then you can simply pull a list of the users related tenants and give them a UI to switch tenants.
Works well with the session tenant strategy wherein you set a session variable to the tenant they selected then when they click on a tenant. Also works with other strategies such as route or path based where the UI basically links them to the correct uri when they select a tenant from a list. Can work with the claim strategy but you have to basically logout/login the user behind the scenes each time they want to change tenants to reset the claim value.
Then for your other backend application data contexts separate from identity the MultiTenantDbContext can still be useful if you need data separation. For needing to see data across tenants if you are using a shared database I recommend combining IgnoreGlobalQueryFilters alongside a where condition to get the results you need. If using separate database per tenant I recommend separate instances of your context via the factory constructor methods as needed and joining up the results in your code, of course this might not scale well above a few tenants.
I am currently attempting to build a multitenant system where a single sign in page (provided by a SPA), is able to perform all the functions of ASP.Net Core Identity. I have some customs requirements due to providing functionality for a mobile app and desktop app. For context, the application is a shift scheduling and time management system.
Requirements:
Data Model context:
Users are connected to Tenants (Organisations) via an Employee class. Organisations create an Employee class. Users have a One to Many relationship with Employees.
Below is some of the implemented code:
MultiTenantStoreDbContext:
ApplicationUser class:
Program.cs
At present, when I generate the ApplicationUser class, it is always bound to an Organisation via the Multitenancy system. What I would like to know is what I am doing wrong. I have looked through the past issues, but very few go into details about implementing Multitenancy in this fashion.
The text was updated successfully, but these errors were encountered: