项目概述:

一般在企业中,用户以WINDOWS的域用户统一的管理,所以以Django快速开发的应用,不得不集成AD域登录。

网上一般采用django-python3-ldap的库来做集成登录,但是本方案中需要同时使用域用户登录以及站点用户登录的功能。所以我们直接改写django的ModelBackend类以及User类来实现。

实现功能

User表中增加一个 是否是域用户的字段,如果登录用户是域用户则采用ldap认证,如果不是域用户还采用Django本身的验证。

实现分析:

一、User表中如何增加字段

Django的auth_user表的字段是由django.contrib.auth.models中的User类控制的。

#Django源码
class User(AbstractUser):
"""
Users within the Django authentication system are represented by this
model. Username and password are required. Other fields are optional.
"""
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'

我们需要对User类进行改写来实现增加字段的功能

步骤一

首先我们需要新建一个my_user_auth的app

python manage.py startapp my_user_auth

步骤二

在my_user_auth的models文件中对User进行重新定义。里面增加了一个is_ad_account的字段用来标识是否是域用户。

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
"""
Users within the Django authentication system are represented by this
model.
Username and password are required. Other fields are optional.
"""
is_ad_account=models.BooleanField('启用域用户登录', default=False)
cn_name = models.CharField(('中文名'), max_length=30, blank=True)
en_name = models.CharField(('英文名'), max_length=150, blank=True) def full_name(self): # 计算字段要显示在修改页面中只能定义在只读字段中
return self.cn_name+'#'+self.en_name class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'

步骤三

在admin中注册自定义的User类

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User class User_exAdmin(UserAdmin):
#查询字段
search_fields = ('username', 'first_name', 'last_name', 'email')
#编辑显示字段,我们在其中添加我们刚才创建的'cn_name', 'en_name', 'is_ad_account
fieldsets = (
(None, {'fields': ('username', 'password')}),
(('Personal info'), {'fields': ('cn_name', 'en_name', 'email','is_ad_account')}),
(('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2'),
}),
)
#显示字段
list_display = ('username', 'email', 'cn_name', 'en_name', 'is_staff') admin.site.register(User, User_exAdmin)

步骤四

修改setting文件中

1、添加INSTALLED_APPS

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#你自定义登录的app名
'my_user_auth',
]

2、添加AUTH_USER_MODEL,将系统的User类替换为你写的User类。

AUTH_USER_MODEL = 'my_user_auth.User'

3、运行makemigrations、migrate。

但是首先要确保是你的Django项目还没有运行任何的makemigrations、migrate。那会导致系统的错误。

4、完成后打开数据库,可以看到my_user_auth_user的表数据表。那么恭喜你,自定义User已经成功了。

二、修改控制登录逻辑的ModelBackend类

User类修改完成后,只需要将登录逻辑修改完成,那么我们的功能也就完成了

先来研究下Django中ModelBackend的源码

步骤一

我们在刚刚新建的app【my_user_auth】中创建一个【backends.py】

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.backends import UserModel
from my_user_auth.ad_auth import ldap_auth class UserBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.is_ad_account:
if ldap_auth(user.username,password) and self.user_can_authenticate(user):
print("域用户登陆成功",user.username)
return user
else:
if user.check_password(password) and self.user_can_authenticate(user):
print("网站账号登陆成功",user.username)
return user

步骤二

修改setting文件中AUTHENTICATION_BACKENDS将'django.contrib.auth.backends.ModelBackend'修改为'my_user_auth.backends.UserBackend'

AUTHENTICATION_BACKENDS = ['my_user_auth.backends.UserBackend']

步骤三

基于ldap3来ldap认证的代码

from ldap3 import Server, Connection, ALL, SUBTREE, ServerPool
#域服务器IP,辅域就行了
LDAP_SERVER_POOL = ["192.168.3.2"]
#LDAP服务端口
LDAP_SERVER_PORT = 389 def ldap_auth(username, password):
ldap_server_pool = ServerPool(LDAP_SERVER_POOL)
#用户以user@abc.net的形式录入
ad_user=f"""{username}@abc.net"""
conn = Connection(ldap_server_pool, user=ad_user, password=password, check_names=True, lazy=False, raise_exceptions=False) conn.open()
conn.bind()
if conn.result["result"]==0:
conn.unbind()
return True
else:
conn.unbind()
return False

步骤四

完成后请在用户维护界面勾选启用域用户登录,那么这个用户就可以用域用户进行认证了。

Django开发文档-域用户集成登录的更多相关文章

  1. [技巧]使用Xcode集成的HeaderDoc自动生成注释和开发文档

    [技巧]使用Xcode集成的HeaderDoc自动生成注释和开发文档     Doxygen本来是一个很好的工具,可是我感觉在mac系统下,如果用doxygen最后生成的CHM文件感觉就不是那么恰当, ...

  2. 【原创】Odoo开发文档学习之:构建接口扩展(Building Interface Extensions)(边Google翻译边学习)

    构建接口扩展(Building Interface Extensions) 本指南是关于为Odoo的web客户创建模块. 要创建有Odoo的网站,请参见建立网站;要添加业务功能或扩展Odoo的现有业务 ...

  3. 若快打码平台python开发文档修改版

    一.打码的作用 在进行爬虫过程中,部分网站的登录验证码是比较简单的,例如四个英文数字随机组合而成的验证码,有的是全数字随机组成的验证码,有的是全中文随机组成的验证码.为了爬虫进行自动化,需要解决自动登 ...

  4. jssip中文开发文档(完整版)

    jsSip开发文档 (官网地址:http://www.jssip.net/) 完整案例demo下载地址: http://download.csdn.net/download/qq_39421580/1 ...

  5. C#微信开发文档

    C#微信开发文档 开发前准备 微信公众平台链接: https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN 开发初期我们使用测 ...

  6. ECMall模板开发文档

    ECMall 模板开发文档 前 言 欢迎阅读 ECMall 模板制作教程,通过阅读本教程可快速上手 ECMall 模板的使用和制作. ECMall 模板制 作要求用户具备 XML . XHTML 和 ...

  7. Android 界面滑动实现---Scroller类 从源码和开发文档中学习(让你的布局动起来)

    在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现..   例子相关博文:Androi ...

  8. Android 滑动界面实现---Scroller类别 从源代码和开发文档了解(让你的移动布局)

    在android学习,行动互动是软件的重要组成部分,其中Scroller是提供了拖动效果的类,在网上.比方说一些Launcher实现滑屏都能够通过这个类去实现.. 样例相关博文:Android 仿 窗 ...

  9. 项目管理之 使用 appledoc 生成开发文档

    写项目时通常会遇到要求写开发文档的需求,但是就源代码来说,文档最好和源码在一起,这样更新起来更加方便和顺手.Objective-C 有一些文档管理工具,doxygen, headdoc 和 apple ...

随机推荐

  1. 动态规划-Minimum Cost to Merge Stones

    2019-07-07 15:48:46 问题描述: 问题求解: 最初看到这个问题的时候第一反应就是这个题目和打破气球的题目很类似. 但是我尝试了使用dp将问题直接转为直接合并到一个堆问题复杂度迅速提高 ...

  2. python之面向对象三大特性: 继承(单继承)

    什么是继承 专业角度: B 继承 A类, B就叫做A的子类,派生类, A叫做B的父类,基类,超类. B类以及B类的对象使用A类的所有的属性以及方法. 字面意思: 继承就是继承父母所有的资产 class ...

  3. 五大经典卷积神经网络介绍:LeNet / AlexNet / GoogLeNet / VGGNet/ ResNet

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! LeNet / AlexNet / GoogLeNet / VGG ...

  4. 我的Keras使用总结(4)——Application中五款预训练模型学习及其应用

    本节主要学习Keras的应用模块 Application提供的带有预训练权重的模型,这些模型可以用来进行预测,特征提取和 finetune,上一篇文章我们使用了VGG16进行特征提取和微调,下面尝试一 ...

  5. rabbitmq++:rabbitmq 三种常用的交换机

    更多 rabbitmq 介绍 首先先介绍一个简单的一个消息推送到接收的流程,提供一个简单的图: 黄色的圈圈就是我们的消息推送服务,将消息推送到 中间方框里面也就是 rabbitMq的服务器: 然后经过 ...

  6. js的预编译

    JavaScript不会完全按照代码的顺序执行,在执行之前会对定义的函数和变量先来一边所谓的预编译处理. 先来说下对变量的预处理: console.log(a) //undefined var a = ...

  7. 感知器基础原理及python实现

    简单版本,按照李航的<统计学习方法>的思路编写 数据采用了著名的sklearn自带的iries数据,最优化求解采用了SGD算法. 预处理增加了标准化操作. ''' perceptron c ...

  8. jdk安装和配置教程

    目录 jdk的下载 jdk的安装 配置环境变量 验证是否配置成功] 一些常见的错误(待更新) 一.首先是jdk的下载 链接:https://pan.baidu.com/s/1ojQDuCwiGSA7A ...

  9. javascript创建函数的方法

    函数对任何语言来说都是一个核心的概念.函数,是一种封装(将一些语句,封装到函数里面). 通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行. ECMAScript中的函数使用funct ...

  10. 手把手教你分析Mysql死锁问题

    前言 前几天跟一位朋友分析了一个死锁问题,所以有了这篇图文详细的博文,哈哈~ 发生死锁了,如何排查和解决呢?本文将跟你一起探讨这个问题 准备好数据环境 模拟死锁案发 分析死锁日志 分析死锁结果 环境准 ...