Coder Social home page Coder Social logo

django_auth_ldap3_ad's People

Contributors

cdobbyn avatar juanfont avatar menesis avatar povtux avatar seancallaway avatar seyhbold avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django_auth_ldap3_ad's Issues

User can't login when member of multiple groups and more then 1000 groups in the domain

When a user logs in, all groups in the domain are fetched and each one is iterated to find if the user is a member. The LDAP query only fetched the first 1000. If a user is a member of a group that's not included in those first 1000 groups, logon will be denied.

This could be solved by adding all groups in LDAP_SUPERUSER_GROUPS, LDAP_STAFF_GROUPS and LDAP_GROUPS_MAP to LDAP_GROUPS_SEARCH_FILTER in a dynamic way. Filtering out all irrelevant groups.

Proposed solution:

  • Do this dynamically in the code instead of leaving it up to the user to configure
  • Put this in the usage documentation with some example code to append the groups to the query in LDAP_GROUPS_SEARCH_FILTER

Case Sensitivity

Not sure how to do a pull request. I updated line 84 to be case insensitive.

uid = User.objects.filter(username__iexact=username).values_list('pk', flat=True)
usr = User.objects.get(pk=uid[0])

Test Connection

Hi,
After install it and configured my Django Server. Is it possible to run a verification that it works?

Thanks
Chris

How to import users and groups

I have a working AD server,

your module works and I can log into admin area of django with my administrators group member.

how can I Import all users and groups to django ?
my config

#Active Directory
LDAP_SERVERS = [
{
'host': '10.172.90.3',
'port': 389,
'use_ssl': False,
},
]
LDAP_ENGINE = "AD"
LDAP_BIND_USER = "cn=intranet,ou=EFEKTUM,dc=ad,dc=efektum,dc=pl"
LDAP_BIND_PASSWORD = ""
LDAP_SEARCH_BASE = "dc=ad,dc=efektum,dc=pl"
LDAP_USER_SEARCH_FILTER = "(&(|(userPrincipalName={0})(sAMAccountName={0}))(objectClass=user))"

DAP_USE_LDAP_GROUPS = True
LDAP_GROUPS_SEARCH_BASE = "dc=ad,dc=efektum,dc=pl"
LDAP_GROUPS_SEARCH_FILTER = "(&(objectClass=group))"
LDAP_GROUP_MEMBER_ATTRIBUTE = "member"
LDAP_SUPERUSER_GROUPS = ["CN=Administratorzy,DC=ad,DC=efektum,DC=pl", ]
LDAP_STAFF_GROUPS = ["CN=IT,OU=PROJEKTY,OU=EFEKTUM,DC=ad,DC=efektum,DC=pl", ]
LDAP_GROUPS_MAP = {
'DPD': "CN=DPD,OU=PROJEKTY,OU=EFEKTUM,DC=ad,DC=efektum,DC=pl",
}
LDAP_ATTRIBUTES_MAP = {
'username': 'sAMAccountName',
'first_name': 'givenName',
'last_name': 'sn',
'email': 'mail',
}

LDAP_USER_BU is not working

Hi,

I set up
LDAP_STORE_BUSINESS_UNIT = { 'CN=xxxx,DC=au': 'XXX', }
in settings.py

And I got a KeyError when I use request.session['LDAP_USER_BU']

request.session['LDAP_USER_DN'] just fine.

Cheers

its not really clear how to deny access if not a member of a group(s) or alternatively deny if in a group

for example if I have a python ldap3 that considers this a deny if found:

conn.search(search_base="DC=adomain,DC=com",
search_filter="(&(objectCategory=person)(sAMAccountName=" + connection_information['AD_Accnt'].split("\",1)[1] + ")(objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=App-X-Deny,OU=Security Groups,DC= adomain,DC=com))",
search_scope=SUBTREE,
attributes = ["sAMAccountName","displayName","mail"],
size_limit=0)

how does one set that up in the settings file? it seems that would be a good addition to the doc. I easily figured out how to grant access, I am not clear on how to deny.

along that line if you look at the doc for the older https://django-auth-ldap.readthedocs.io/en/latest/

it has a specific way to state that with

AUTH_LDAP_REQUIRE_GROUP = "cn=enabled,ou=groups,dc=example,dc=com"
AUTH_LDAP_DENY_GROUP = "cn=disabled,ou=groups,dc=example,dc=com"

or

AUTH_LDAP_REQUIRE_GROUP = (
LDAPGroupQuery("cn=enabled,ou=groups,dc=example,dc=com")
| LDAPGroupQuery("cn=also_enabled,ou=groups,dc=example,dc=com")
) & ~LDAPGroupQuery("cn=disabled,ou=groups,dc=example,dc=com")

having something like this as a feature would be nice.

Attributes saving as 1 character in DB

When Django saves the user in the DB for all attributes it is chopping all but the first character. This ultimately causes authentication to fail and when trying to login again it tries to create another user and runs into a unique constraint error.

I'm currently using Django 1.11 and Python 2.7.

I will try with some previous versions of Django to see if I get the same results. I'll also dig around/debug and see if I can find anything that pops out at me.

Example

Is there an example configuration available?

License

Hi,
Any chance to consider the license to be the same of django (BSD), or Apache or MIT?

Regards,
Pedro

Python 2 incompatibility: "str" in auth.py

In auth.py, update_user does:

                    if isinstance(attributes[settings.LDAP_ATTRIBUTES_MAP[attr]], str):
                        attribute_value = attributes[settings.LDAP_ATTRIBUTES_MAP[attr]]
                    else:
                        attribute_value = attributes[settings.LDAP_ATTRIBUTES_MAP[attr]][0]

This looks like it's meant to accept either a string or a list in attributes[settings.LDAP_ATTRIBUTES_MAP[attr]].

But the "str" in there is treacherous. On python 2, that's the name of the "bytes" type, while the Unicode string type is called "unicode".

So, on python2, this code will see a string and think it's some kind of list. And because a string is indexable, it reduces the username to just the first letter!

Some possible ways of fixing this:

  • Is the code really supposed to accept a list or tuple in place of a username? If not, maybe the easiest solution is simply to drop this check.
  • Instead of isinstance(X, str) say isinstance(X, type(u'')).
  • Depend on six and use six.text_type instead of str.

When registering new users from AD, only the first character of any field is saved

When creating new users, only the first character of the field gets saved in auth_users. For instance:
In LDAP when givenName=Andrew, only 'A' gets saved.

The line of code causing it is 309 in auth.py:
setattr(user, attr, attributes[settings.LDAP_ATTRIBUTES_MAP[attr]][0])

From my settings.py

LDAP_ATTRIBUTES_MAP = {
    'username': 'sAMAccountName',
    'first_name': 'givenName',
    'last_name': 'sn',
    'email': 'mail',
}

Changing line 309 to this fixes it for me
setattr(user, attr, attributes[settings.LDAP_ATTRIBUTES_MAP[attr]])

Thx,
Andy

last_login not set

Hi,

Thanks for the very useful library :)
I noticed that Django's last_login attribute is not set upon authentication. Could you add this?

Thanks

ldap3.core.exceptions.LDAPInvalidPortError: port must be an integer

kali@kali:~/AD/LDAP/ldapdomaindump$ sudo ldapdomaindump lkdaps://192.168.202.132 -u 'ADLAB\s1account' -p User1@123

/usr/local/bin/ldapdomaindump:4: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
import('pkg_resources').run_script('ldapdomaindump==0.9.4', 'ldapdomaindump')
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/ldap3/core/server.py", line 114, in init
port = int(hostport) or port
^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: '//192.168.202.132'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/bin/ldapdomaindump", line 4, in
import('pkg_resources').run_script('ldapdomaindump==0.9.4', 'ldapdomaindump')
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 722, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 1561, in run_script
exec(code, namespace, namespace)
File "/usr/local/lib/python3.11/dist-packages/ldapdomaindump-0.9.4-py3.11.egg/EGG-INFO/scripts/ldapdomaindump", line 3, in
ldapdomaindump.main()
File "/usr/local/lib/python3.11/dist-packages/ldapdomaindump-0.9.4-py3.11.egg/ldapdomaindump/init.py", line 940, in main
s = Server(args.host, get_info=ALL)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/ldap3/core/server.py", line 118, in init
raise LDAPInvalidPortError('port must be an integer')
ldap3.core.exceptions.LDAPInvalidPortError: port must be an integer

No option to disable saving passwords

Please modify auth.py to give the option to disable saving LDAP passwords locally or to use a dummy password. I've modified line 171 in auth.py to use a dummy password at the moment with no ill effect.

ldap3.core.exceptions.LDAPInvalidPortError: port must be an integer

django 3.1
python 3.9.6
...lib\site-packages\ldap3\core\server.py", line 118
try:
port = int(hostport) or port
except ValueError:
if log_enabled(ERROR):
log(ERROR, 'port <%s> must be an integer', port)
raise LDAPInvalidPortError('port must be an integer')

settings:
LDAP_SERVERS = [
{
'host': 'confidential',
'port': 389, #also tried init(389), still fails
'use_ssl': False,
'get_info': 'NONE',
},
]

class Login(View):
template = 'login.html'

def get(self, request):
    _form = AuthenticationForm()
    return render(request, self.template, {'form': _form})

def post(self, request, *args, **kwargs):
    _form = AuthenticationForm(request.POST)
    _username = request.POST['username']
    _password = request.POST['password']
    _user = authenticate(request, username=_username, password=_password)
    if _user is not None:
        login(request, _user)
        return HttpResponseRedirect('/')
    else:
        return render(request, self.template, {'form': _form})  

Debug output

I think I got the code working, but it can't login.
Is it possible to debug what's going on?

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

This doesn't give my any idea what's going on.

SQL Error during login (LDAP3ADBackend.authenticate())

Testing this LDAP/AD module, but after the successful login we get an error.

ProgrammingError at /login/
function upper(text[]) does not exist
LINE 1: ...user" WHERE UPPER("auth_user"."username"::text) = UPPER(ARRA...
                                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

Followed the error with the python debugger and it crashes within the authentication() method. This is because the result is a list and not the user itself.

try:
      # try to retrieve user from database and update it
       username_field = getattr(settings, 'LDAP_USER_MODEL_USERNAME_FIELD', 'username') 
       lookup_username = user_attribs[settings.LDAP_ATTRIBUTES_MAP[username_field]]
       usr = user_model.objects.get(**{"{0}__iexact".format(username_field): lookup_username})

Changing lookup_username to lookup_username[0] solves the issue, but is this the solution?
Do other people encounter the same issue?

view example

Hello. I already wrote all needed information to settings.py, but unfortunatly I do not understand what I should wright in views.py file. Can you help me and provide view file example?

Duplicate entry 'USERS.NAME' for key 'username'

I'm getting the error about a duplicate entry (Duplicate entry 'USERS.NAME' for key 'username') if I try to login after having already logged in once and populated the db with my user name. If I delete the user row from the auto_user table then it will let me log in again.

I've also noticed that none of the AD groups are being created in the django db. I'm not sure if this is expected behavior or not; I'm very new to django.

Here's my config:

LDAP_ENGINE = 'AD'

LDAP_BIND_USER = "DN FOR ACCOUNT"
LDAP_BIND_PWD = "PASSWORD"

LDAP_SEARCH_BASE = "DN FOR LOCATION"
LDAP_USER_SEARCH_FILTER = "(&(sAMAccountName=%s)(objectClass=user))"

LDAP_ATTRIBUTES_MAP = {
    'username': 'sAMAccountName',
    'first_name': 'givenName',
    'last_name': 'sn',
    'email': 'mail',
}

LDAP_STORE_USER_DN = True

LDAP_SERVERS = [
    {
        'host': 'IP.ADDR',
        'port': 389,
        'use_ssl': False,
    },
    {
        'host': 'IP.ADDR',
        'port': 389,
        'use_ssl': False,
    },
]

LDAP_USE_LDAP_GROUPS = True
LDAP_GROUPS_SEARCH_BASE = "DN FOR LOCATION"
LDAP_GROUPS_SEARCH_FILTER = "(&(objectClass=group))"
LDAP_GROUP_MEMBER_ATTRIBUTE = "member"
LDAP_SUPERUSER_GROUPS = ["DN FOR ACCOUNT", ]
LDAP_STAFF_GROUPS = ["DN FOR ACCOUNT", ]
LDAP_GROUPS_MAP = {
    'my_admins': "DN FOR ACCOUNT",
    'my_users': "DN FOR ACCOUNT",
}

IndexError in case LDAP attribute returns empty list

We use the newest version 1.6.33

We have an exception when logging in,
IndexError: list index out of range, in

django_auth_ldap3_ad/auth.py in init_and_get_ldap_user at line 162
The value of user_attribs[attrib] is [], i.e. the empty list.

I think in that case, we'd need to set None. The code in question has been introduced with #30

Case sensitive comparison for LDAP_GROUP_MAP

Hello,

First thanks a lot for this great module, vert usefull.

I juste face some issue that take le some Time to correct.

The LDAP search is case insensitive, and the comparison which is uses in the LDAP_GROUP_MAP is not.

So there is case where the group will be find in the LDAP and user not added in the Django group.

Maybe the comparison should uses a .lower() somewhere :
if resp['dn'].lower() == settings.LDAP_GROUPS_MAP[grp].lower()

For exemple .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.