AD Authentication

117 views
Skip to first unread message

Ian Boskip

unread,
Sep 20, 2021, 1:34:38 AM9/20/21
to Jam.py Users Mailing List
Hi,

I've been trying to get AD authentication working for access control to my Jam application.

I've installed ldap3 and this script;

# import class and constants
from ldap3 import Server, Connection, ALL

def on_login(task, login, password, ip, session_uuid):
    users = task.app.admin.sys_users.copy(handlers=False)
    users.set_where(f_login=login, f_password=password)
    users.set_where(f_login=login)
    users.open()
    if users.record_count() == 1:
        return {
          'user_id': users.id.value,
          'user_name': users.f_name.value,
          'role_id': users.f_role.value,
          'role_name': users.f_role.display_text
        }      

    users = task.users.copy(handlers=False)
    users.set_where(login=login, password=password)
    users.open()
    if users.record_count() == 1:
        return {
          'user_id': users.id.value,
          'user_name': users.name.value,
          'role_id': users.role.value,
          'role_name': users.role.display_text
        }      

    result = None

# define the server
    s = Server('10.79.1.2', port=389, use_ssl=False)  #define an unsecure LDAP server, requesting info on DSE and schema


# define the connection
    try:
            c = Connection(s, user='CN=%s,OU=Users,OU=...,DC=...,DC=com' % login, password=password)
# perform the Bind operation

            if not c.bind():
                #print('error in bind', c.result)
                raise Exception('You are not allowed!')
                print('You are not allowed!')
            else:
                result = {
                    'user_id': login,
                    'user_name': login,
                    #'user_id': login,
                    #'user_name': login,
                    'role_id': 1,
                    'role_name': 'Admin'
                }
# below except is not working
    except Exception as e:
        print("authentication error")

    return result

(obviously with the correct OU and DC, tested with ldapsearch and working.)
When trying to login this is the error produced (logging in with a 'local' Jam account still works!);

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/jam.py-5.4.114-py3.7.egg/jam/wsgi.py", line 387, in login
    user_info = task.on_login(task, form_data, {'ip': ip, 'session_uuid': session_uuid})
TypeError: on_login() missing 2 required positional arguments: 'ip' and 'session_uuid'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/jam.py-5.4.114-py3.7.egg/jam/wsgi.py", line 391, in login
    user_info = task.on_login(task, form_data['login'], form_data['password'], ip, session_uuid)
  File "prints", line 17, in on_login
    users = task.users.copy(handlers=False)
AttributeError: 'Task' object has no attribute 'users'

Any help is much appreciated!

Ian.

Drazen D. Babic

unread,
Sep 20, 2021, 2:15:11 AM9/20/21
to Jam.py Users Mailing List
Hi mate

You can see it in action in here:

This is ldap bound connection with username jam01 and the same for password.
You can test this with jam02 (pwd jam02), and jam03 (no access, pwd jam03).

This lines:
 File "prints", line 17, in on_login
    users = task.users.copy(handlers=False)

basically you do not have User in the Users table (on Project/Users) which is accessing Jam.

There must be the user there, but password is not needed since coming from ldap.
Still, I would have an password b/c ldap might be down or something, so on_login can be modified.

Btw, there is 
users = task.users.copy 
and
users = task.app.admin.sys_users.copy

Decide which one of two ;)

D.

Drazen D. Babic

unread,
Sep 20, 2021, 2:49:28 AM9/20/21
to Jam.py Users Mailing List
Screenshot from 2021-09-20 14-41-18.png

Yes, 

the code is the same as per above. 
I'm not giving access to change anything on builder, this users are not Builder Administrators :) 

Ian Boskip

unread,
Sep 22, 2021, 11:26:14 PM9/22/21
to Jam.py Users Mailing List
Hi All,

Just sharing my working solution in case anyone is interested :)

We wanted to accomplish the following;

1. Password authentication against AD
2. Only allowing users to log in who are added to the JAM user list
3. Using the same login name as for their office computers even though we have two domain names in use
4. have the login name case-insensitive

This is what I did;

1. In the application builder click on 'Task' and then on Server module.
2. Add the following script (make sure to adjust lines 14,15 and 17 to suit your details)

# import class and constants
from ldap3 import Server, Connection, ALL

def on_login(task, login, password, ip, session_uuid):
    login=login.lower()
    result = None
    users = task.app.admin.sys_users.copy(handlers=False)

    users.set_where(f_login=login)
    users.open()
    if users.record_count() == 1:
        user_name=users.f_name.value
        role_id=users.f_role.value
        role_name=users.f_role.display_text
        s = Server('<ip-address>', port=389, use_ssl=False)
        c = Connection(s, user="%s@<domain name>" % (login), password=password)
        if not c.bind():
            c = Connection(s, user="%s@<alternative domain name>" % (login), password=password)
            if c.bind():
                result = {
                    'user_id': login,
                    'user_name': user_name,
                    'role_id': role_id,
                    'role_name': role_name

                }
        else:
            result = {
                'user_id': login,
                'user_name': user_name,
                'role_id': role_id,
                'role_name': role_name
            }
    return result

3. Add a user (this version will take the name and role from the Jam user not the AD user) there is no need to populate the password as it will authenticate against AD.

You are now able to login as that user.

Troubleshooting;

For troubleshooting you can use this script on the Linux prompt of your server to check your AD authentication;

root@p:~/ptest# cat ptest.py
#!/usr/bin/python


from ldap3 import Server, Connection, ALL
def on_login(login, password):
    result = None
    s = Server('<ip-address>', port=389, use_ssl=False)
    c = Connection(s, user="%s@<domain-name>" % (login), password=password)
    if not c.bind():
       print("authentication error")
    else:
       print("authentication success")
on_login("<user>","<password>")
root@p:~/ptest#

Enjoy!

Ian.

Reply all
Reply to author
Forward
0 new messages