django special multitenancy with keycloak - django

i am planning a web application with multiple tenants (or i call it companies).
Every model in django has a foreign key to a specific company, to separate the data. It is possible that a user has access to multiple companies.
You can see this in the following diagram:
The user can login over a login page and then the user sees all companies he related to. Now he can choose one of the company to work with the data.
Up to this point i have no problem.
Some of the companies would like to use their own active directory or other systems to synchronize theirs users with my web application and authenticate them.
I found keycloak during my search and it looks like good for my plan because i also would like to split my web application in smaller services in a kubernetes cluster.
But i can't find informations about if keycloak work with my plan and the requirement for linking multiple active directories or other systems.
I think keycloak would have to check the username (email address) and decide from the domain if an external service is configured for the domain or the normal login page is used.
For example for domain abc.de is configured a active directory and for domain example.com another active directory. If User 3 or User 2 try to log in they should redirect to the active directory of their domain.
But User 1 should still login over the normal login page with username and password.
But is that possible with keycloak?

Related

How to map one social account to several user account with django-allauth

I need to map one social account (created on a Django server with django-oauth-toolkit) to several different logins in a Django website. I already managed to connect and the server passes all allowed accounts so that the client connects as one of them.
I'd like to add the possibility to prompt for the choice of which of the accounts should be used. I'm currently connecting the user in the pre_social_login method of the account adapter.
The only idea I have is to persist in the session the available accounts and redirect to a page to select the preferred one. I'd like to understand if there's a better way.

How can I log a Django user into WooCommerce without prompting?

My workflow takes the user from a Django web application to a WooCommerce store. For example, they fill in example.com/register and are taken to store.com/checkout.
Both applications are backed by the same LDAP database, so at the moment I prompt the user to enter their credentials a second time.
This is functional, but not the greatest UX. How can I transport them from the Django to store domain and sign them into the store, without user intervention?
(Because the domains are different and I expect third-party cookies to be disabled, I obviously can't generate a cookie for the store domain while still in the Django domain.)

How to reference user account in FreeIPA database to user account in Web app database

My company has decided to use FreeIPA in order to make available Single Sign On feature for our employees. I am not familiar at all with Kerberos/LDAP and similar because i have never used those technologies before.
We have 70 users - they have Windows OS machines and SSO should be used for several Python (Django) web apps, WordPress web sites and possibly for Roundcube web email and OpenVPN access. They don't have access to web servers at all so SSH accounts are not important for this story.
Our python web app has database table with users' data which is in relation with some other tables and it is very important for us to have every single user added to those tables (via our web app interface) because otherwise our app will not work properly.
Having that in mind, i would like to know if there is a way somehow to reference user from FreeIPA's database to our web app's and wordpress' databases, example below:
Not every user has access to every web app and not every user has the same privileges in those apps.
We have already defined user privileges in every web app separately and everything works perfect, so main aim is just to make avaliable SSO for our users. I don't want to bother with user groups and privileges in FreeIPA system, will be i able to avoid that?
When user gets Kerberos ticket i want those web apps to recognize his/her account which is referenced to corresponding user account in FreeIPA database, and so has certain privileges in those apps.
In this scenario it is obvious that i will have to add every new user two times - in FreeIPA database and in web app's database, but that's not a problem, i just want to connect/reference those user accounts somehow.
EDIT to Michael Ströder's answer:
As i see, i would have to add every existing user manually to FreeIPA with "--uid" command because FreeIPA gives those attributes to every user automatically. I agree, i would not use user names for UID but only integers. So, i have imagined to make it like this - i would have to link every user's uid number to application's DB user's table ID column. Let say, if John has UID #7 he should also have ID #7 in WordPress wp_users table, and that looks fine to me. I think i could easily manage this in my custom python app, but i'm unsure how to manage this in WordPress, is there some plugin that could be use for such things? I've found AuthLDAP but i'm not sure if that is the right way to do it? Thanks in advance
The usual way is to have unique and persistent user names (String), usually stored in attribute uid in FreeIPA (or other LDAP servers) and use this as key in your application's DB table.
Note that uid does not contain the POSIX-UID (Integer) which is actually stored in attribute uidNumber.
I'd strongly recommend not to derive user names stored in uid from personal names because these often change. Also you should never reuse user names.
FreeIPA also has attribute nsUniqueId which contains a UUID generated during creation of the entry. It will not be modified during life-time of the entry. If you want to use that you have to take care that entries are not deleted/re-created by an external identity management systems all the time.
(Other LDAP servers are using standard attribute entryUUID).

Multi-tenant Centralized Authentication Server

I am trying to create a centralized authentication server for multiple Django apps (APIs). I've seen posts/recommendations but none fit exactly what I am looking for.
Overview:
Users can be associated to one or multiple projects
Users have same credentials to all projects they are associated to
Use JSON Web Tokens - use payload to add user data, sub-domain (project) to route to, role, etc
Sub-domain will not be used for login. All users will login to same site and will be routed to project they are associated to (or given list if there are multiple). SSO is optional.
Questions/uncertainties:
Q: Should the authentication tokens be created on the authentication server or on each project? ie) Each user having one auth token for all projects or have one auth token for each project?
Q: Roles will be stored in each app. I would like to send the roles along with the authentication token in the JWT. Should this data be redundantly stored on the authentication server? Another other way would be for the authentication server to access the project databases. What is the best way to handle this? Users will have different roles for each project.
Q: Auth server will have basic user information (email/username, password, first/last name, etc). Since foreign keys can't be used between databases I can use a user proxy based on usernames to create the user on each project. Do the app servers need to have access to which authentication tokens are valid?
Taking advantage of pre-existing software:
Another approach I had in mind was to use django-tenant-schemas which takes advantage of Postgres schemas where each one of my projects would be a schema (currently using MYSQL databases). Does it make sense to take advantage of this?
Can I take advantage of an IdP service to offload some of the authentication? Does this easily tie into the Django auth layer?
Your question seems to be multiple so I would split the answer too:
ABOUT THE USERS
Since your users are not part of your "mutitencancy model" you have two options here:
Replicate your user data among the different tenant databases (via triggers and what not).
Write your own authentication middleware that verifies users in the right database (lets call it root database since now on). You can use user ids to from the root database and verify manually that they match, which is a bad idea.
That means your database schema will be something like this:
root database (all common data here)
project 1 database (with it's own user data or referencing root)
project 2 database (with it's own user data or referencing root)
Now for authentication tokens
You have the same options as above:
Keep them in the root database and write your own middleware.
Replicate them.
How to implement the whole thing
Since your use case is pretty particular, you may encounter some resistance from existing software. But creating your own multitenant solution is not that hard

Two login systems in the same Flask application

I want to have two login systems in the same application. There is main site for the 'owners', the owners can have 'portals'. Each portal will have his own login system, this time for the 'users'. Users within the portal will have roles (admin, editor, etc).
Something like:
site.com -> owners loging
site.com/portal1 -> users login
site.com/portal2 -> other users login
Owners and users are stored in different tables.
I dont know how to achive this with Flask-Login. How should I proceed?
Other alternatives I'm thinking are:
Split this application in two, one for the main site and the other
one for portals.
Join users and owners in the same table, and make the distiction if the user is owner or not. This I think is not desired, because they have different attributes.
You can use third party frameworks to handle authentication in your application. I use Auth0 and have nothing to complain. They are really simple to use and have integration with Flask.
From their home page:
Add authentication to your web and mobile apps in under 10 minutes;
Using Auth0, you can define, for example, a callback URL based on the user role. So you can call /owner if the user is an owner or /portalX if the user is not an owner.
This way you don't have to develop many and many security layers to secure users login.