Python项目有哪些常用LDAP连接与认证的方法以及他们的特性

django-auth-ldapldap3 都是用于与 LDAP(轻量级目录访问协议)服务器(如 Active Directory)交互的 Python 库,但它们在设计目标、实现方式和集成方式上有显著的不同。理解它们的区别对于选择适合你项目需求的解决方案至关重要。以下是对这两个库的详细比较,以及它们在配置后端身份验证方面的不同之处。

概述

django-auth-ldap

  • 类型: Django 认证后端扩展
  • 依赖库: python-ldap
  • 主要功能: 提供与 LDAP 服务器集成的 Django 认证后端,实现用户身份验证和同步
  • 安装复杂度: 依赖于 python-ldap,需要编译 C 扩展,特别是在 Windows 上安装较为复杂

ldap3

  • 类型: 通用 LDAP 客户端库
  • 依赖库: 纯 Python 实现(无需编译 C 扩展)
  • 主要功能: 提供与 LDAP 服务器进行各种交互的 API,包括查询、修改、添加和删除条目
  • 安装复杂度: 简单,跨平台兼容性好,只需通过 pip 安装

详细比较

1. 实现方式与依赖

  • django-auth-ldap:
    • 基于 python-ldap,这是一个绑定到 OpenLDAP C 库的 Python 包。
    • 需要编译 C 扩展,因此在安装时需要相应的编译工具(如 Microsoft Visual C++ Build Tools 在 Windows 上)。
    • 提供现成的 Django 认证后端,简化了与 Django 认证系统的集成。
  • ldap3:
    • 纯 Python 实现,不依赖任何外部 C 库。
    • 易于安装,适用于各种操作系统,无需额外的编译工具。
    • 提供灵活且功能丰富的 API,用于与 LDAP 服务器进行各种交互。

2. 安装与配置

  • django-auth-ldap:

    • 安装:

      pip install django-auth-ldap
      

      由于依赖 python-ldap,在 Windows 上可能会遇到编译问题(如缺少编译工具)。

    • 配置:

      settings.py 中进行配置,主要涉及 LDAP 服务器的连接信息、用户搜索基础等。例如:

      import ldap
      from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
      
      AUTH_LDAP_SERVER_URI = "ldap://your-ad-server.example.com"
      
      AUTH_LDAP_BIND_DN = "cn=admin,dc=example,dc=com"
      AUTH_LDAP_BIND_PASSWORD = "your-password"
      
      AUTH_LDAP_USER_SEARCH = LDAPSearch(
          "ou=users,dc=example,dc=com",
          ldap.SCOPE_SUBTREE,
          "(sAMAccountName=%(user)s)"
      )
      
      AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
          "ou=groups,dc=example,dc=com",
          ldap.SCOPE_SUBTREE,
          "(objectClass=groupOfNames)"
      )
      AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
      
      AUTH_LDAP_REQUIRE_GROUP = "cn=enabled_users,ou=groups,dc=example,dc=com"
      
      AUTH_LDAP_USER_ATTR_MAP = {
          "first_name": "givenName",
          "last_name": "sn",
          "email": "mail",
      }
      
      AUTH_LDAP_ALWAYS_UPDATE_USER = True
      
      AUTHENTICATION_BACKENDS = (
          'django_auth_ldap.backend.LDAPBackend',
          'django.contrib.auth.backends.ModelBackend',
      )
      
  • ldap3:

    • 安装:

      pip install ldap3
      
    • 配置:

      需要手动编写 Django 认证后端,以利用 ldap3 进行身份验证。以下是一个自定义认证后端的示例:

      1. 在 Django 项目中创建自定义认证后端

        在你的 Django 应用目录中(例如 your_app),创建一个文件 auth_backend.py

        # your_app/auth_backend.py
        
        from django.contrib.auth.backends import BaseBackend
        from django.contrib.auth.models import User
        from ldap3 import Server, Connection, ALL, NTLM
        
        class LDAPBackend(BaseBackend):
            def authenticate(self, request, username=None, password=None):
                server = Server('ldap://your-ad-server.example.com', get_info=ALL)
                conn = Connection(server, user=f'DOMAIN\\{username}', password=password, authentication=NTLM)
                if not conn.bind():
                    return None
        
                # 查询用户信息
                conn.search('DC=example,DC=com', f'(sAMAccountName={username})', attributes=['cn', 'mail', 'givenName', 'sn'])
                if not conn.entries:
                    return None
        
                user_entry = conn.entries[0]
                try:
                    user = User.objects.get(username=username)
                except User.DoesNotExist:
                    user = User(username=username, first_name=user_entry.givenName.value, last_name=user_entry.sn.value, email=user_entry.mail.value)
                    user.set_unusable_password()
                    user.save()
        
                return user
        
            def get_user(self, user_id):
                try:
                    return User.objects.get(pk=user_id)
                except User.DoesNotExist:
                    return None
        
      2. settings.py 中配置认证后端

        # settings.py
        
        AUTHENTICATION_BACKENDS = (
            'your_app.auth_backend.LDAPBackend',  # 自定义认证后端
            'django.contrib.auth.backends.ModelBackend',
        )
        
      3. 同步数据库(如果需要)

        如果你的自定义后端涉及创建用户或其他模型更改,确保进行数据库迁移:

        python manage.py makemigrations
        python manage.py migrate
        

3. 功能差异

  • django-auth-ldap:
    • 优点:
      • 专为 Django 设计,集成简单。
      • 提供现成的功能,如用户同步、组权限管理等。
      • 配置简单,通过 Django 设置完成大部分工作。
    • 缺点:
      • 依赖 python-ldap,在 Windows 上安装可能遇到困难。
      • 灵活性较低,主要聚焦于认证和用户同步。
  • ldap3:
    • 优点:
      • 纯 Python 实现,安装简单,跨平台兼容性好。
      • 灵活性高,可以根据需求自定义各种 LDAP 操作。
      • 不依赖外部 C 库,减少了环境配置的复杂性。
    • 缺点:
      • 需要手动编写 Django 认证后端,集成工作量较大。
      • 缺少 django-auth-ldap 提供的现成功能,如用户同步,需要自行实现。

4. 选择建议

  • 如果你能够解决 python-ldap 的安装问题(例如,使用预编译的 Wheel 文件),并且需要快速集成 LDAP 认证,那么 django-auth-ldap 是一个不错的选择。
  • 如果你在 Windows 上遇到安装 python-ldap 的问题,或者希望避免编译依赖,ldap3 是更好的选择。尽管需要手动编写认证后端,但安装和跨平台兼容性使其更加灵活。

详细配置示例1-django-auth-ldap

以下提供了详细的配置示例。

使用 django-auth-ldap 进行配置

1. 安装依赖

确保已成功安装 django-auth-ldap 和其依赖 python-ldap。如果仍遇到安装问题,参考之前文章的解决方案使用预编译的 Wheel 文件进行安装。

2. 配置 settings.py
# settings.py

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType

# LDAP服务器地址
AUTH_LDAP_SERVER_URI = "ldap://your-ad-server.example.com"

# 绑定DN和密码
AUTH_LDAP_BIND_DN = "cn=admin,dc=example,dc=com"
AUTH_LDAP_BIND_PASSWORD = "your-password"

# 用户搜索基础
AUTH_LDAP_USER_SEARCH = LDAPSearch(
    "ou=users,dc=example,dc=com",
    ldap.SCOPE_SUBTREE,
    "(sAMAccountName=%(user)s)"
)

# 组搜索基础
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    "ou=groups,dc=example,dc=com",
    ldap.SCOPE_SUBTREE,
    "(objectClass=groupOfNames)"
)
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()

# 要求用户属于某个组
AUTH_LDAP_REQUIRE_GROUP = "cn=enabled_users,ou=groups,dc=example,dc=com"

# 映射LDAP属性到Django用户模型
AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
}

# 每次登录时更新Django用户信息
AUTH_LDAP_ALWAYS_UPDATE_USER = True

# 配置认证后端
AUTHENTICATION_BACKENDS = (
    'django_auth_ldap.backend.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

# 可选:日志记录
import logging
logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
3. 使用 Django Admin 管理权限

django-auth-ldap 支持将 LDAP 组映射到 Django 组和权限。

我们可以在 settings.py 中进一步配置组映射:

# settings.py

from django_auth_ldap.config import LDAPGroupQuery

# 将LDAP组映射到Django组
AUTH_LDAP_GROUP_MAPPING = {
    "cn=admins,ou=groups,dc=example,dc=com": {"name": "Admin"},
    "cn=users,ou=groups,dc=example,dc=com": {"name": "User"},
}

# 将LDAP组权限映射到Django组权限
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_MIRROR_GROUPS = True

这样,当用户属于某个 LDAP 组时,他们将自动被添加到相应的 Django 组,并继承相应的权限。

使用 ldap3 进行配置

1. 安装 ldap3
pip install ldap3
2. 创建自定义认证后端

在你的应用中(例如 your_app),创建 auth_backend.py文件:

# your_app/auth_backend.py

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User
from ldap3 import Server, Connection, ALL, NTLM

class LDAPBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None):
        # LDAP服务器配置
        LDAP_SERVER = 'ldap://your-ad-server.example.com'
        LDAP_DOMAIN = 'DOMAIN'
        LDAP_BASE_DN = 'DC=example,DC=com'

        # 连接LDAP服务器
        server = Server(LDAP_SERVER, get_info=ALL)
        user_dn = f'{LDAP_DOMAIN}\\{username}'

        conn = Connection(server, user=user_dn, password=password, authentication=NTLM)
        if not conn.bind():
            return None

        # 查询用户信息
        conn.search(
            search_base=LDAP_BASE_DN,
            search_filter=f'(sAMAccountName={username})',
            attributes=['cn', 'mail', 'givenName', 'sn']
        )

        if not conn.entries:
            return None

        user_entry = conn.entries[0]

        # 获取或创建Django用户
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            user = User(
                username=username,
                first_name=user_entry.givenName.value,
                last_name=user_entry.sn.value,
                email=user_entry.mail.value
            )
            user.set_unusable_password()
            user.save()

        return user

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
3. 配置 settings.py
# settings.py

AUTHENTICATION_BACKENDS = (
    'your_app.auth_backend.LDAPBackend',  # 自定义LDAP认证后端
    'django.contrib.auth.backends.ModelBackend',
)
4. 配置视图和权限

根据需要,可以使用 Django 的权限系统来管理不同管理员的权限。例如:

# views.py

from django.contrib.auth.decorators import login_required, permission_required
from django.shortcuts import render
from ldap3 import Server, Connection, ALL, NTLM

@login_required
@permission_required('your_app.manage_users', raise_exception=True)
def manage_users(request):
    # 使用 ldap3 与 AD 交互,管理用户
    server = Server('ldap://your-ad-server.example.com', get_info=ALL)
    conn = Connection(server, user='DOMAIN\\admin_user', password='admin_password', authentication=NTLM)
    if not conn.bind():
        return render(request, 'error.html', {'message': '无法连接到 AD 服务器'})

    # 示例:获取所有用户
    conn.search('DC=example,DC=com', '(objectClass=person)', attributes=['cn', 'mail'])
    users = conn.entries

    return render(request, 'manage_users.html', {'users': users})
5. 管理权限和组

在 Django Admin 中,你可以创建自定义权限,并将其分配给不同的用户或组:

  1. 定义自定义权限

    在你的 Django 应用的 models.py 中,为模型添加自定义权限:

    # your_app/models.py
    
    from django.db import models
    
    class SomeModel(models.Model):
        # 模型字段...
        class Meta:
            permissions = [
                ("manage_users", "Can manage AD users"),
                ("manage_groups", "Can manage AD groups"),
                # 其他权限...
            ]
    
  2. 同步数据库

    python manage.py makemigrations
    python manage.py migrate
    
  3. 分配权限

    在 Django Admin 中,为不同的用户或组分配相应的权限。

3. 选择哪一个?

  • django-auth-ldap 适用于希望快速集成 LDAP 认证的 Django 项目,尤其是当你能成功安装其依赖项(如 python-ldap)时。它提供了现成的解决方案,减少了手动配置的工作量。
  • ldap3 适用于希望更灵活地控制 LDAP 交互,或者在安装 python-ldap 遇到困难(如 Windows 上编译问题)时。虽然需要编写自定义认证后端,但它避免了编译依赖的问题,安装更为简便。

我的理解

  • django-auth-ldap 是一个专为 Django 设计的认证后端扩展,简化了与 LDAP(如 AD)的集成,但依赖于 python-ldap,在某些环境下安装可能存在一些问题。
  • ldap3 是一个功能强大且易于安装的 LDAP 客户端库,适合需要更高灵活性的项目。通过编写自定义认证后端,可以实现与 Django 认证系统的深度集成,同时避免了编译依赖的问题。

根据你的项目需求和开发环境,选择适合的库。如果你主要遇到安装问题,ldap3 可能是更好的选择,尤其是在 Windows 环境下。

如果你选择使用 ldap3,以下是一个更完整的示例,展示如何创建自定义认证后端并在 Django 中使用它。


详细配置示例2-ldap3

使用 ldap3 和 Django 进行 AD 身份验证

1. 安装依赖
pip install django ldap3
2. 创建 Django 项目和应用
django-admin startproject ad_management
cd ad_management
python manage.py startapp your_app
3. 配置 settings.py

编辑 ad_management/settings.py

# settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'your_app',  # 添加你的应用
]

AUTHENTICATION_BACKENDS = (
    'your_app.auth_backend.LDAPBackend',  # 自定义LDAP认证后端
    'django.contrib.auth.backends.ModelBackend',
)

# 配置静态文件
STATIC_URL = '/static/'

# 其他必要配置...
4. 创建自定义认证后端

your_app 目录下创建 auth_backend.py文件:

# your_app/auth_backend.py

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User
from ldap3 import Server, Connection, ALL, NTLM

class LDAPBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None):
        if username is None or password is None:
            return None

        # LDAP服务器配置
        LDAP_SERVER = 'ldap://your-ad-server.example.com'
        LDAP_DOMAIN = 'DOMAIN'
        LDAP_BASE_DN = 'DC=example,DC=com'

        # 连接LDAP服务器
        server = Server(LDAP_SERVER, get_info=ALL)
        user_dn = f'{LDAP_DOMAIN}\\{username}'

        conn = Connection(server, user=user_dn, password=password, authentication=NTLM)
        if not conn.bind():
            return None

        # 查询用户信息
        conn.search(
            search_base=LDAP_BASE_DN,
            search_filter=f'(sAMAccountName={username})',
            attributes=['cn', 'mail', 'givenName', 'sn']
        )

        if not conn.entries:
            return None

        user_entry = conn.entries[0]

        # 获取或创建Django用户
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            user = User(
                username=username,
                first_name=user_entry.givenName.value,
                last_name=user_entry.sn.value,
                email=user_entry.mail.value
            )
            user.set_unusable_password()
            user.save()

        return user

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
5. 配置 URL 和视图

your_app/views.py 中创建一个简单的视图,用于展示认证状态:

# your_app/views.py

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required

def user_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect('dashboard')
        else:
            return render(request, 'your_app/login.html', {'error': 'Invalid credentials'})
    return render(request, 'your_app/login.html')

@login_required
def dashboard(request):
    return render(request, 'your_app/dashboard.html')

def user_logout(request):
    logout(request)
    return redirect('login')

ad_management/urls.py 中配置 URL:

pythonCopy code# ad_management/urls.py

from django.contrib import admin
from django.urls import path
from your_app import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.user_login, name='login'),
    path('dashboard/', views.dashboard, name='dashboard'),
    path('logout/', views.user_logout, name='logout'),
]
6. 创建模板

your_app/templates/your_app/ 目录下创建 login.htmldashboard.html

login.html:

<!-- your_app/templates/your_app/login.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <!-- 引入 AdminLTE CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1.0/dist/css/adminlte.min.css">
</head>
<body class="hold-transition login-page">
    <div class="login-box">
        <div class="login-logo">
            <a href="#"><b>AD</b>Login</a>
        </div>
        <div class="card">
            <div class="card-body login-card-body">
                <form method="post">
                    {% csrf_token %}
                    <div class="input-group mb-3">
                        <input type="text" name="username" class="form-control" placeholder="Username" required>
                        <div class="input-group-append">
                            <div class="input-group-text">
                                <span class="fas fa-user"></span>
                            </div>
                        </div>
                    </div>
                    <div class="input-group mb-3">
                        <input type="password" name="password" class="form-control" placeholder="Password" required>
                        <div class="input-group-append">
                            <div class="input-group-text">
                                <span class="fas fa-lock"></span>
                            </div>
                        </div>
                    </div>
                    {% if error %}
                        <div class="alert alert-danger">{{ error }}</div>
                    {% endif %}
                    <div class="row">
                        <div class="col-12">
                            <button type="submit" class="btn btn-primary btn-block">Login</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!-- 引入 AdminLTE JS -->
    <script src="https://cdn.jsdelivr.net/npm/admin-lte@3.1.0/dist/js/adminlte.min.js"></script>
</body>
</html>

dashboard.html:

<!-- your_app/templates/your_app/dashboard.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dashboard</title>
    <!-- 引入 AdminLTE CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1.0/dist/css/adminlte.min.css">
</head>
<body class="hold-transition sidebar-mini">
    <div class="wrapper">
        <!-- Navbar -->
        <nav class="main-header navbar navbar-expand navbar-white navbar-light">
            <!-- Left navbar links -->
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link" href="#" data-widget="pushmenu"><i class="fas fa-bars"></i></a>
                </li>
                <li class="nav-item d-none d-sm-inline-block">
                    <a href="#" class="nav-link">Home</a>
                </li>
            </ul>
            <!-- Right navbar links -->
            <ul class="navbar-nav ml-auto">
                <li class="nav-item">
                    <a href="{% url 'logout' %}" class="nav-link">Logout</a>
                </li>
            </ul>
        </nav>
        <!-- /.navbar -->

        <!-- Main Sidebar Container -->
        <aside class="main-sidebar sidebar-dark-primary elevation-4">
            <!-- Brand Logo -->
            <a href="#" class="brand-link">
                <span class="brand-text font-weight-light">AD Management</span>
            </a>

            <!-- Sidebar -->
            <div class="sidebar">
                <!-- Sidebar user panel -->
                <div class="user-panel mt-3 pb-3 mb-3 d-flex">
                    <div class="info">
                        <a href="#" class="d-block">{{ request.user.username }}</a>
                    </div>
                </div>

                <!-- Sidebar Menu -->
                <nav class="mt-2">
                    <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
                        <li class="nav-item">
                            <a href="{% url 'manage_users' %}" class="nav-link">
                                <i class="nav-icon fas fa-users"></i>
                                <p>
                                    Manage Users
                                </p>
                            </a>
                        </li>
                        <!-- 添加更多导航项 -->
                    </ul>
                </nav>
                <!-- /.sidebar-menu -->
            </div>
            <!-- /.sidebar -->
        </aside>

        <!-- Content Wrapper -->
        <div class="content-wrapper">
            <section class="content">
                <div class="container-fluid">
                    <h1>Welcome to AD Management Dashboard</h1>
                    <!-- 你的内容 -->
                </div>
            </section>
        </div>
        <!-- /.content-wrapper -->

        <!-- Footer -->
        <footer class="main-footer">
            <strong>&copy; 2024 <a href="#">Your Company</a>.</strong> All rights reserved.
        </footer>
    </div>
    <!-- ./wrapper -->

    <!-- 引入 AdminLTE JS -->
    <script src="https://cdn.jsdelivr.net/npm/admin-lte@3.1.0/dist/js/adminlte.min.js"></script>
</body>
</html>
7. 创建视图用于管理用户

your_app/views.py 中添加管理用户的视图:

# your_app/views.py

from django.contrib.auth.decorators import login_required, permission_required
from django.shortcuts import render
from ldap3 import Server, Connection, ALL, NTLM

@login_required
@permission_required('your_app.manage_users', raise_exception=True)
def manage_users(request):
    # LDAP服务器配置
    LDAP_SERVER = 'ldap://your-ad-server.example.com'
    LDAP_USER = 'DOMAIN\\admin_user'
    LDAP_PASSWORD = 'admin_password'
    LDAP_BASE_DN = 'DC=example,DC=com'

    # 连接LDAP服务器
    server = Server(LDAP_SERVER, get_info=ALL)
    conn = Connection(server, user=LDAP_USER, password=LDAP_PASSWORD, authentication=NTLM)
    if not conn.bind():
        return render(request, 'your_app/error.html', {'message': '无法连接到 AD 服务器'})

    # 查询所有用户
    conn.search(
        search_base=LDAP_BASE_DN,
        search_filter='(objectClass=person)',
        attributes=['cn', 'mail', 'givenName', 'sn']
    )
    users = conn.entries

    return render(request, 'your_app/manage_users.html', {'users': users})

创建 manage_users.html 模板:

<!-- your_app/templates/your_app/manage_users.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Manage Users</title>
    <!-- 引入 AdminLTE CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1.0/dist/css/adminlte.min.css">
</head>
<body class="hold-transition sidebar-mini">
    <div class="wrapper">
        <!-- 包含导航栏和侧边栏,与 dashboard.html 相同 -->
        {% include 'your_app/dashboard.html' %}
        
        <!-- Content Wrapper -->
        <div class="content-wrapper">
            <section class="content">
                <div class="container-fluid">
                    <h2>Manage AD Users</h2>
                    <table class="table table-bordered table-striped">
                        <thead>
                            <tr>
                                <th>用户名</th>
                                <th>邮箱</th>
                                <th>名字</th>
                                <th>姓氏</th>
                            </tr>
                        </thead>
                        <tbody>
                            {% for user in users %}
                            <tr>
                                <td>{{ user.cn }}</td>
                                <td>{{ user.mail }}</td>
                                <td>{{ user.givenName }}</td>
                                <td>{{ user.sn }}</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </div>
            </section>
        </div>
        <!-- /.content-wrapper -->

        <!-- Footer -->
        <footer class="main-footer">
            <strong>&copy; 2024 <a href="#">Your Company</a>.</strong> All rights reserved.
        </footer>
    </div>
    <!-- ./wrapper -->

    <!-- 引入 AdminLTE JS -->
    <script src="https://cdn.jsdelivr.net/npm/admin-lte@3.1.0/dist/js/adminlte.min.js"></script>
</body>
</html>
8. 分配权限
  1. 定义自定义权限

    your_app/models.py 中定义权限:

    # your_app/models.py
    
    from django.db import models
    
    class UserProfile(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE)
        # 其他用户相关字段
    
        class Meta:
            permissions = [
                ("manage_users", "Can manage AD users"),
                ("manage_groups", "Can manage AD groups"),
            ]
    
  2. 同步数据库

    python manage.py makemigrations
    python manage.py migrate
    
  3. 在 Django Admin 中分配权限

    • 登录 Django Admin。
    • 为需要管理 AD 用户的管理员用户分配 manage_users 权限。
9. 测试认证
  1. 运行开发服务器

    python manage.py runserver
    
  2. 访问登录页面

    打开浏览器,访问 http://localhost:8000/login/,使用 AD 用户凭据登录。

  3. 访问仪表板和管理用户页面

    登录后,访问 http://localhost:8000/dashboard/,并尝试访问 http://localhost:8000/manage_users/

最后的总结

django-auth-ldap vs ldap3

特性django-auth-ldapldap3
类型Django 认证后端扩展通用 LDAP 客户端库
依赖python-ldap(需要编译 C 扩展)纯 Python 实现,不需要编译
安装难度高(尤其在 Windows 上)低,简单通过 pip install ldap3 安装
配置复杂度简单,通过 Django settings.py 配置需要手动编写自定义认证后端
功能提供现成的认证和用户同步功能提供灵活的 LDAP 操作 API,适用于多种用途
跨平台兼容性依赖 python-ldap 的编译,跨平台支持有限(Windows 上较难)高,纯 Python 实现,跨平台兼容性好
灵活性主要聚焦于认证和用户同步,灵活性有限高,适用于各种自定义的 LDAP 交互需求

选择建议

  • 选择 django-auth-ldap:
    • 如果你希望快速集成 LDAP 认证,并且能够成功安装其依赖项(如在 Linux 环境下)。
    • 需要现成的功能,如用户同步和组权限映射,减少开发工作量。
  • 选择 ldap3:
    • 如果你在 Windows 上开发,或者希望避免编译依赖问题。
    • 需要更高的灵活性,能够根据项目需求自定义 LDAP 交互。
    • 愿意编写自定义的 Django 认证后端,投入一些开发工作以实现所需功能。

无论选择哪种方法,都可以实现与 Active Directory 的集成。django-auth-ldap 提供了一个开箱即用的解决方案,而 ldap3 则提供了更高的灵活性和跨平台的兼容性。根据你的项目需求、开发环境和对灵活性的要求,选择最适合的库来实现你的 AD 管理工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arthur古德曼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值