ldap_plugin issue ?

94 views
Skip to first unread message

Guglielmo SAVINO

unread,
Apr 22, 2025, 11:00:37 AM4/22/25
to py4web

Hello,

I believe there is an issue within the auth_plugin/ldap_plugin.py utility.

The get_user_groups_from_ldap(self, con, username) method expects to receive an ldap object as its first con functional parameter.

However, within the is_user_in_allowed_groups method, it is called as follows:

self.groups = self.get_user_groups_from_ldap(username, password)

with the two strings username and password. This, correctly, generates an error.
Is there something I'm missing? 

I'd like to propose a solution, but I'm not clear on the underlying mechanism, so I'm asking for assistance.

Guglielmo 


Massimo DiPierro

unread,
Apr 22, 2025, 11:14:59 AM4/22/25
to Guglielmo SAVINO, py4web
Ciao Guglielmo,

You are probably right. I have not used or tested it much but I will try fix it over the weekend, unless somebody can get there sooner.

Massimo

--
You received this message because you are subscribed to the Google Groups "py4web" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4web+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/py4web/18fcd4b5-ae5f-457f-aae4-4612cf8dbcbcn%40googlegroups.com.

Nour Sawas

unread,
May 5, 2025, 3:01:48 AM5/5/25
to py4web
Hallo,

did you make any progress here?

I am also trying to use the LDAP plugin for authorization. The first Problem that I noticed is that the function check_credentials(self, username, password) is defined twice in the class LDAPPlugin. I commented the last one out. I could login with mode="ad", but the stored email is not my organisation email. It is always storing the email with @example.com instead

I used the path :  auth/login which is the default from the login form

using the path : auth/plugin/ldap/login is giving  AttributeError: 'LDAPPlugin' object has no attribute 'handle_request' (the same as this issue: https://groups.google.com/g/py4web/c/udtHMTu2hZY)

I would appreciate any help

Nour

Rakesh Singh

unread,
Jun 3, 2025, 5:02:03 PM6/3/25
to py4web
I've made the following changes to get mine to work. Commenting out or removing the check_credentials function at the end of the file should resolve the issue obtaining the user's firstname, lastname and email attributes.



diff --git a/py4web/utils/auth_plugins/ldap_plugin.py b/py4web/utils/auth_plugins/ldap_plugin.py
index 9a60506e..5b4a6b7e 100644
--- a/py4web/utils/auth_plugins/ldap_plugin.py
+++ b/py4web/utils/auth_plugins/ldap_plugin.py
@@ -794,7 +794,7 @@ class LDAPPlugin(UsernamePassword):
             con.start_tls_s()
         return con
 
-    def get_user_groups_from_ldap(self, con, username):
+    def get_user_groups_from_ldap(self, username=None, password=None):
         """
         Get all group names from ldap where the user is in
         """
@@ -832,6 +832,10 @@ class LDAPPlugin(UsernamePassword):
         logger = self.logger
         groups = self.groups
 
+        # if username is None, return empty list
+        if username is None:
+            return []
+
         logger.info("[%s] Get user groups from ldap" % str(username))
         #
         # Get all group name where the user is in actually in ldap
@@ -847,7 +851,17 @@ class LDAPPlugin(UsernamePassword):
                         domain.append(x.split("=")[-1])
                 username = "%s@%s" % (username, ".".join(domain))
             username_bare = username.split("@")[0]
+            con = self._init_ldap()
             con.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
+            try:
+                if bind_dn:
+                    # need to search directory with an admin account 1st
+                    con.simple_bind_s(bind_dn, bind_pw)
+                else:
+                    # credentials should be in the form of user...@domain.tld
+                    con.simple_bind_s(username, password)
+            except (ldap.INVALID_CREDENTIALS, ldap.OPERATIONS_ERROR):
+                return []
             # In cases where ForestDnsZones and DomainDnsZones are found,
             # result will look like the following:
             # ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,
@@ -880,7 +894,6 @@ class LDAPPlugin(UsernamePassword):
                 ldap_groups_of_the_user.append(
                     str(group[group_name_attrib][0], encoding="utf-8")
                 )
-                print(ldap_groups_of_the_user)
 
         logger.debug("User groups: %s" % ldap_groups_of_the_user)
         return list(ldap_groups_of_the_user)
@@ -889,5 +902,6 @@ class LDAPPlugin(UsernamePassword):
             filterstr = filterstr[1:-1]  # parens added again where used
         return []
 
-    def check_credentials(self, username, password):
+#    def check_credentials(self, username, password):
         return self.is_user_in_allowed_groups(username, password)
+#

Lykke Pedersen

unread,
Jun 17, 2025, 4:27:06 AM6/17/25
to py4web
We want to connect to Active Directory (AD) using ldap. Is it possible to use the py4web login and connect it to AD?And does it work?

Is the py4web documentation for this up to date?
 It says:

from py4web.utils.auth_plugins.ldap_plugin import LDAPPlugin LDAP_SETTING = { 'mode': 'ad', 'server': 'my.domain.controller', 'base_dn': 'cn=Users,dc=domain,dc=com' } auth.register_plugin(LDAPPlugin(**LDAP_SETTINGS))

Warning: it needs the python-ldap module. On Ubuntu, you should also install some developer’s libraries in advance with sudo apt-get install libldap2-dev libsasl2-dev.

What do we need to install?  ldap3? py4web-auth-ldap? 

José Pinho

unread,
Jun 25, 2025, 6:25:42 AM6/25/25
to py4web
Hi, I recently did this install. It does work, for me.

It's as in the docs :

1 - pip install python-ldap (Which may need : sudo apt-get install -y libldap2-dev libsasl2-dev)
2 - On your settings.py :
...
USE_LDAP=True
LDAP_SETTINGS = {
    "mode": "ad",
    "server": "your_ldapserver_here",  # FQDN or IP of one Domain Controller
    "base_dn": "your_basedn_here",  # base dn, i.e. where the users are located
    }
... You might need to ask your sys admin for the base_dn. It typically resembles something like : "dc=mycompany, dc=com", or "dc=mycompany, dc=tree", ...
3 - On your controllers.py :
 On each action which needs auth, set the decorator :
   @action.uses(auth)


Reply all
Reply to author
Forward
0 new messages