DJango LDAP统一认证集成

  • 安装

    pip install django==3.2
    pip install djangorestframework
    pip install django-python3-ldap
  • 在首次migrate之前,创建UserModel,扩展AbstractUser类

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    ​
    ​
    class LdapUser(AbstractUser):
        """LDAP用户表"""
        department = models.CharField(verbose_name='部门', max_length=128, null=True, blank=True)
        employee_number = models.CharField(verbose_name='工号', max_length=16, null=True, blank=True)
        employee_status = models.IntegerField(verbose_name='员工状态', default=0)
        display_name = models.CharField(verbose_name='姓名', max_length=64, null=True, blank=True)
        employee_type = models.CharField(verbose_name='员工类型', max_length=16, null=True, blank=True)
        location = models.CharField(verbose_name='员工位置', max_length=32, null=True, blank=True)
        bad_pwd_count = models.IntegerField(verbose_name='账号错误计数', default=0)

  • django-python3-ldap配置

    # settings.py
    ​
    # Auth队列
    AUTHENTICATION_BACKENDS = (
        'django_python3_ldap.auth.LDAPBackend',
        'django.contrib.auth.backends.ModelBackend',
    )
    ​
    # 指定自己定义的AuthModel
    AUTH_USER_MODEL = 'ldap.LdapUser'
    ​
    ################### LDAP配置 ######################
    LDAP_AUTH_URL = ["ldap://172.16.20.11:389"]
    LDAP_AUTH_USE_TLS = False
    LDAP_AUTH_SEARCH_BASE = "OU=Domain Users,DC=transwarp,DC=io"
    LDAP_AUTH_CONNECTION_USERNAME = "xinchen.luan"
    LDAP_AUTH_CONNECTION_PASSWORD = "*************"
    LDAP_AUTH_OBJECT_CLASS = "user"
    LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",)
    LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data"
    LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_active_directory_principal"
    LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = "transwarp.io"
    # Ldap服务器与Model字段映射关系
    LDAP_AUTH_USER_FIELDS = {
        "username": "cn",
        "first_name": "givenName",
        "last_name": "sn",
        "email": "mail",
        "department":"department",
        "employee_number":"employeeNumber",
        "employee_status":"userAccountControl",
        "display_name":"displayName",
        "employee_type":"employeeType",
        "location":"description",
        "bad_pwd_count":"badPwdCount",
    }
    ​
    # 登陆日志
    LOGGING = {
        "version": 1,
        "disable_existing_loggers": False,
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
            },
        },
        "loggers": {
            "django_python3_ldap": {
                "handlers": ["console"],
                "level": "INFO",
            },
        },
    }
  • 同步数据库

  • ldap_sync_users

  • 查看数据库

  • 简单登陆验证

    from django.shortcuts import render, HttpResponse,redirect
    from django.views.decorators.csrf import csrf_exempt
    from django.contrib import auth
    from django.contrib.auth.decorators import login_required
    ​
    @csrf_exempt
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
    ​
        username = request.POST.get('username')
        password = request.POST.get('password')
    ​
        user_obj = auth.authenticate(request, username=username, password=password)
        if user_obj:
            auth.login(request,user_obj)
            path = request.GET.get('next') or '/index/'
            return redirect(path)
        return render(request, 'login.html', {'error_msg': '登陆失败'})
    ​
    def logout(request):
        auth.logout(request)
        return redirect('/login/')
    ​
    @login_required
    def index(request):
        return render(request,'index.html',{"user":request.user})
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>欢迎登陆</h1>
    <form method="post">
        <input type="text" name="username" placeholder="用户名" required="true">
        <input type="password" name="password" placeholder="密码" required=true>
    ​
        <span style="color: red">{{ error_msg }}</span>
        <button type="submit">登 录</button>
    </form>
    </body>
    </html>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>ITOPS</h1>
    <h3>当前用户:{{ user.last_name }}{{ user.first_name }}</h3>
    <hr>
    ​
    <h3>统一账号信息</h3>
    <li>账号: {{ user.username }}</li>
    <li>姓名: {{ user.display_name }}</li>
    <li>部门: {{ user.department }}</li>
    <li>邮箱: {{ user.email }}</li>
    <li>工号: {{ user.employee_number }}</li>
    <li>状态: {{ user.employee_status }}</li>
    <li>类型: {{ user.employee_type }}</li>
    <li>备注: {{ user.location }}</li>
    <li>密码错误计数:{{ user.bad_pwd_count }}</li>
    <hr>
    ​
    <h3>接口信息</h3>
    <li></li>
    <a href="/logout/">注销</a>
    </body>
    </html>

image-rztc.png