abp.io Resolve Tenant On Login Screen - multi-tenant

How can I resolve tenant based on the given credential without using swich tenant section which is available on login screen?

I think this is not applicable since you enable MultiTenant Option and you don't use additional unique key for tenants,
Because in case of enabling Multitenant, the user Identification based on Username and TenantId , as you can find in your DB 2 users with same username and different TenantId, so your system will not be able to identify the targeted user using username only.
In your case you can implement this identification using other ways
Identify the targeted tenant using the domain or subdomain check the documentation here https://docs.abp.io/en/abp/latest/Multi-Tenancy
Another option is identify the tenant from the second part of user email, for example username#tenant1 , username#tenant2 , this is applicable if you restricted your users to register using specific tenants domains

Related

Assign project-level user to multiple tenants

Cannot find anywhere on Google Identity Platform docs that clearly describe whether it's possible to assign a single user to multiple tenants. see https://cloud.google.com/identity-platform/docs/multi-tenancy-managing-tenants
My project needs the capability to have a single user be able to login to multiple, separate tenants. Currently, I have to create a new user on every tenant I want to be able to login to. This is not good because each new user I create has a different uid and separate password management. For a single user, I want to be able to maintain the same uid across tenants so the associated user data can be consistent as well.
I was thinking there would be some way to create a user at the project level (not tenant level) and then assign that user to specific tenants?
Some random thoughts: The docs say some things about migrating users between tenants, perhaps that is one way. Also was thinking that creating a tenant user with my existing project-level uid would somehow merge them so the uid and password management is the same?
Edit: I found this conceptual discussion to be helpful: https://softwareengineering.stackexchange.com/questions/403274/multitenancy-with-cross-tenant-users
what I gathered from that link is that SSO is separate from multi-tenancy. So I'm trying to figure out an SSO solution on top of multi-tenancy google idp. Any code solutions/suggestions for how to add SSO on top of multi-tenant google identity platform?
If you need the same user across tenants maybe you should instead rely on the user email, custom claims, federated ID (eg. user.providerData[0].uid). When you get an ID token for the user you have access to this same information regardless of the tenant or user.uid.

Outsystems:Is it possible to have same user in different tenants in a Multi-tenant application

I created a multi-tenant application where each tenant have different set of users. I am trying to implement a functionality where same user might exist in different tenants. Does outsystems provide such functionality or I have to create my custom logic ?
Right now, I did create a user having same username in 2 different tenants and during login I am showing user to select tenants. But on changing tenants and logging to that tenant, the environment doesn't switch to that tenant that user has selected.
Below is the image of the logic of switching tenants and logging in the customer.
During debugging I saw that after executing TenantSwitch action it did change the Site.TenantID property but after User_Login action is reverted to the first tenant not the one user selected.
When you use User_Login(), the system will log you in the first Tenant it finds in the DB that has that username, thus ignoring your TenantSwitch().
So, if you want to login to a specific Tenant in your case, you need to be more explicit and instead use the Login() action - after the tenant switch.
For a thorough explanation of this, with example code, please check out the following deepdive Master Class on Multi-Tenancy starting around the 27:20 minute mark.
This isn't available out of the box as OutSystems assigns users (and all entities) to a specific tenant. Entities belonging to single tenanted modules are assigned to the default tenant.
OutSystems uses a hidden .Tenant_Id attribute on each entity to indicate which tenant that user belongs to. You can unhide this attribute for the users entity by selecting it, clicking More... and then ticking the relevant box in the Advanced tab. You can then access the attribute directly, but be aware this will hinder OutSystems' ability to do some of the stuff it does automatically to ensure that you access tenant specific data.
When you use the User_Login action OutSystems will deduce which tenant to use from the User.Tenant_Id attribute regardless of which tenant you've switched it to previously. The user would need an account for each tenant they need to use, but there's no reason this couldn't be done behind the scenes with OS fetching the correct username before logging in. You'd need to ensure they all stay in sync though, especially the passwords ofc.

How to authenticate against a specific Organization?

I'm trying to build a multi-tenant application using Stormpath. The stack being used is Angular + Express. I'm using the 'Directory-per-Organization' strategy to organize my multi-tenant accounts. My Login form has a 'Organization ID' form field for user to specify the organization’s nameKey.
Is there a specific format in which this field needs to be passed to the stormpath-express backend? Stormpath-Angular SDK has no mention of this. Assuming there is no specific format, I tried adding a preLoginHandler on the stormpath-express side to retrieve the org Id form field mentioned above and set a {accountStore : {nameKey : myOrgNameKey }} on the request body. This however does not authenticate against the specified organization. Instead, it tries to match against all the organizations mapped to the application. I tested this my typing in invalid random strings for Org ID field.
As an aside, Stormpath’s site (api.stormpath.com/login) too does not seem to authenticate against the specified tenant Key. As long as the username and password credentials are fine, I can type in any string in the tenant field and it seems to log me in fine.
I want the username-password credentials to be checked only against the specified organization key and not against all the organizations mapped to the application. How do I go about this ?

MVC Multi Tennat Application how to add sub site

I have an intranet application for which the URL is as follows
http:\\ServerName]\RunLog\
I am adding another department/tenant/group of users which will utilize the same instance of the application and same database. Their data will be different from the existing users. I am planning to add new column foreign key in each table to identify the specific tenant. I authenticate users windows authentication. I am thinking that the access to the application will be as follows
http:\[ServerName]\Platform1\RunLog
http:\[ServerName]\Platform2\RunLog
So for the above URL, how could I go about achieving that in the Application? I know how to make the table changes in SQL server, Updating the Entities, Updating the linq code in the controllers to pull up respective tennant data. Any help to get me started would be appriciated.
Kindly note that as you have given in your post, it is possible to identify the tenant's based on their URL. The table that contains the tenant details will also contain their url. So you will identify the tenant based on the URL. After identifying the tenant, we can authenticate the user's using the found tenant id / tenant code, get the tenant's configuration or settings using the same tenant id / tenant code.
I hope that you could have all the other entities of the application with a column called as TenantId. This will help you to fetch the data based on tenant. Your only change will be in the data access layer where you will filter the data that you retrieve from the Database.
Let me know if you have any other clarifications regarding the other specifics of this implementation.

Storing necessary OpenID information

I'm trying to implement OpenID authentication for my site. Here's the scenario:
I want the user to be able to
login using just openId(user can just get verified by visiting openid provider. no need to create a custom account with email-password),
Via email/password (user has registered in site by filling out a form)
Attach open id(s) to his/her accounts (openids + email for one account).
Now I don't know what credentials I should store for open id. and not sure about the DB schema. Here's the database schema:
Table: Users
UserId => PK
... => Custom info. Not related to authentication.
Table: Authentication
AuthenticationId => PK
LoginId => (when custom site membership => email address) (when openId => openid unique address)
UserId => FK to Users.
Provider =>(when custom site membership => "CUSTOM") (when openId => openid provider address)
Password => filled when using custom membership. empty when using open id.
Now when a user logs in, whether by using openid/custom membership, I just look at authentication table and look for credentials and get the appropriate user. If no users exist, I create a new user and add an entry in authentication table.
The main question: Is storing Provider and LoginId (see the above comments to see what is being stored in these fields) enough for storing openid authentication? Should I store any additional data so that when the user returns I can authenticate him/her based on my saved data?
Do you suggest any other (more efficient) approach to implement this?
Thank you.
Store the ClaimedIdentifier for the openid user--not the Provider address. The Claimed Identifier is what the OpenID protocol verifies is unique for the user and also potentially provides portability across OpenID Providers.
Also, because OpenID 2.0's Claimed Identifiers may be deprecated by OpenID Connect (an unfinished successor to OpenID 2.0), it may also be in your best interest to record the OpenID Provider Endpoint URI and the email address asserted by the Provider in the user record. For now, do not use these as part of your authentication flow, but by recording them, you'll be able to later determine which email addresses you 'trust' (i.e. suppose you decide email addresses asserted by Google are trustworthy) and allow the user to thereby migrate their account to an OpenID Connect one using that verified email address. This will also mitigate against the danger of your web site's Realm (usually http://yourdomainname.com) changing and causing all your Google's user Claimed Identifiers to change, which can only really be recovered from via their email address, tragically.
I also recommend you use different tables for the different auth types. There are a couple of advantages here. The most important one is that architecturally it makes it more difficult to have introduce a security hole into your web site that might allow someone to enter in (for example) an OpenID into the username field and a blank password and have it show up as a database match and login without any real authentication happening. Secondly, it provides a more flexible model in case you want to add a third authentication mechanism rather than making your 'Authentication' table grow horizontally for all users. For example, OAuth 2.0 and "OpenID Connect" will each probably introduce new types of authentication to your site when you add support for them over the years, and adding new tables to handle the new types of data seem to fit better.
We just store the openid claim url. You may want to request additional information from the provider such as the user's name. The most important thing is to separate membership and authentication.
Our schema was
Profiles
--------
UserId
FirstName
LastName
etc.
Users
-----
Username
Password
Profiles.UserId is simply a string property that stores either the users internal username or their openId claim url, depending on how they registered.
Upon successful authentication (either using an internal username/password or external provider) we just set their authentication cookie using either their internal username or their claim url. Getting the user's profile is then just a matter of finding the profiler where (UserId == User.Identity.Name).
This has the advantage that a user can choose to change how they authenticate at any point (perhaps switching to an internal account or using a different provider).

Resources