如何在 django 中实现 ldap 身份验证(没有管理员凭据) [英] How to implement ldap authentication(without admin credentials) in django

查看:30
本文介绍了如何在 django 中实现 ldap 身份验证(没有管理员凭据)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的设置:Django-3.0、Python-3.8、django_auth_ldap
我的组织中有 LDAP 服务器(Active Directory 服务器).我正在构建一个 Django 应用程序,它为所有用户提供一些操作.
我知道 Django 具有内置的用户身份验证机制,但它会验证用户是否存在于用户模型数据库中.

My setup: Django-3.0, Python-3.8, django_auth_ldap
I have LDAP Server (Active Directory Server) in my organization. I am building a Django Application which serves some operations for all the users.
I know Django has built-in User Authentication mechanism, But it authenticates if users are present in User Model Database.

但我的要求是.
所有用户条目都在 LDAP 服务器(活动目录)中.使用正确的用户凭据 LDAP 服务器对我进行身份验证.
我在 Django 'accounts' 应用中创建了一个登录页面,
1.每当我从登录页面输入用户名和密码时,它应该使用我的组织LDAP服务器进行身份验证.
2. 登录后,我必须为登录用户保留会话 5 分钟.(Django 身份验证会话)

But my requirement is.
All user entries are in LDAP Server(Active Directory). Using proper user credentials LDAP server authenticates me.
I Created a Login Page in Django 'accounts' app,
1. whenever I enter username and password from Login Page, it should Authenticate using My Organization LDAP Server.
2. After Login I have to hold the session for the logged in user for 5 active minutes. (Django auth session)

我看到 django_auth_ldap 包为我的目的提供了一些见解.
我在 settings.py 中有这些内容.

I saw django_auth_ldap package gives some insight for my purpose.
I have these contents in settings.py.

import ldap

##Ldap settings
AUTH_LDAP_SERVER_URI = "ldap://myldapserver.com"
AUTH_LDAP_CONNECTION_OPTIONS = {ldap.OPT_REFERRALS : 0}
AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s, OU=USERS,dc=myldapserver, dc=com"
AUTH_LDAP_START_TLS = True

#Register authentication backend
AUTHENTICATION_BACKENDS = [
            "django_auth_ldap.backend.LDAPBackend",

            ]

views.py 中调用身份验证.

Calling authenticate in views.py.

from django_auth_ldap.backend import LDAPBackend
def accounts_login(request):
    username = ""
    password = ""
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        auth = LDAPBackend()
        user = auth.authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect("/")
        else:
            error = "Authentication Failed"
            return render(request, "accounts/login.html", 'error':error)

    return render(request, "accounts/login.html")

但使用上述方法总是无法通过 LDAP 服务器进行身份验证.

But using above method always authenticate fails with the LDAP Server.

如果我使用普通的 python simple_bind_s() 调用,身份验证对同一个 LDAP 服务器工作正常.

If I call using normal python simple_bind_s(), authentication is working fine to same LDAP server.

import ldap
def ldap_auth(username, password):
    conn = ldap.initialize(myproj.settings.LDAP_AUTH_URI)
    try:
        ldap.set_option(ldap.OPT_REFERRALS, 0)
        #ldap.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
        conn.simple_bind_s(username, password)
    except ldap.LDAPError as e:
        return f'failed to authenticate'

    conn.unbind_s()
    return "Success"

有人可以建议我按照我的要求使 LDAPBackend 身份验证工作吗?

Can anybody suggest me to make LDAPBackend Authentication work as per my requirement ?

注意:我没有 LDAP 服务器的管理员权限.

Note: I do not have admin permission of LDAP Server.

推荐答案

这就是我将如何使用 ldap3 而没有 django_auth_ldap 包.

This is how I would do it with ldap3 and without django_auth_ldap packages.

1 - 在 your_app/backends.py 中创建自定义 AuthenticationBackend :

1 - Create a custom AuthenticationBackend in your_app/backends.py :

import logging

from ldap3 import Server, Connection
from ldap3.core.exceptions import LDAPBindError

from django.conf import settings
from django.contrib.auth import get_user_model



logger = logging.getLogger(__name__)
UserModel = get_user_model()


class LDAPBackend:

    def authenticate(self, request, username=None, password=None, **kwargs):
        # set username to lowercase for consistency
        username = username.lower()
        # get the bind client to resolve DN
        logger.info('authenticating %s' % username)
        # set your server
        server = Server(settings.LDAP_HOST, get_info=ALL)
        try:
            conn = Connection(server, f"{username}@{settings.LDAP_DOMAIN}", password=password, auto_bind=True)
        except LDAPBindError as e:
            logger.info('LDAP authentication failed')
            logger.info(e)
            return None
        user = UserModel.objects.update_or_create(username=username)
        return user

    def get_user(self, user_id):
        try:
            return UserModel._default_manager.get(pk=user_id)
        except UserModel.DoesNotExist:
            return None

2 - 在 settings.py


AUTHENTICATION_BACKENDS = [
    'your_app.backends.LDAPBackend', 
    'django.contrib.auth.backends.ModelBackend'
]

这允许您使用 django 的本机功能进行身份验证,并且可以与管理员一起使用.

This allows you to use django's native function for authentication, and it work with the admin.

要让会话只工作 5 分钟,请将此设置添加到您的 settings.py 文件中:

To have session only work for 5 minutes, add this setting to your settings.py file :

SESSION_COOKIE_AGE = 5 * 60

让我知道它是否适合您.

Let me know if it works for your.

这篇关于如何在 django 中实现 ldap 身份验证(没有管理员凭据)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆