07: Django 使用ldap登录、注销等
目录:Django其他篇
05:ModelForm 数据验证 & 生成html & 数据库操作
1.1 配置ldap认证
参考博客:https://www.cnblogs.com/dreamer-fish/p/5474289.html
官网地址:https://pypi.org/project/django-auth-ldap/1.3.0/
1、django使用ldap认证需要安装下面两个模块(这里是在linux下测试的)
1.安装Python-LDAP(python_ldap-2.4.25-cp27-none-win_amd64.whl)pip install python_ldap-2.4.25-cp27-none-win_amd64.whl
2.安装django-auth-ldap(django-auth-ldap-1.2.8.tar.gz)(下载:https://pypi.python.org/pypi/django-auth-ldap),Windows下也可以使用 python setup.py install
3. 安装成功后运行命令,运行成功表示安装成功: from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion, GroupOfNamesType
2、LDAP用户验证基本原理
1. 每个用户在LDAP系统中有一个唯一的DN值,例如配置文件中默认的admin用户在LDAP中的DN值是uid=admin,ou=system,dc=eoncloud,dc=com,
2. 其中eoncloud.com是域名,system是组名,admin是用户名,有些LDAP用cn而不是uid来生成DN
3. 在这种系统中admin的DN看起来像这样cn=admin,ou=system,dc=eoncloud,dc=com,无论是uid还是cn或是别的前缀,django-ldap-auth都是用dn来验证用户和获取用户信息的
4. 假设用户输入的帐号及密码是: test, password,django-auth-ldap有2个方式来获取用户的DN
1)使用AUTH_LDAP_USER_DN_TEMPLATE提供的模板生成DN.如uid=%(user)s,ou=users,dc=eoncloud,dc=com,
其中%(user)s会被替换成用户名,这样最终的DN就是 uid=test,ou=users,dc=eonclooud,dc=com.
2)使用AUTH_LDAP_GROUP_SEARCH.如果没有配置AUTH_LDAP_USER_DN_TEMPLATE,那么django-auth-ldap会使用
AUTH_LDAP_BIND_DN和AUTH_LDAP_BIND_PASSWORD提供的dn与密码根据AUTH_LDAP_GROUP_SEARCH提供的查询条件去查找test用户,
如果查不到,验证失败,如果查到用户,就使用返回的数据生成test的DN.
利用第2步生成DN值与密码尝试访问LDAP系统,如果访问成功,则验证共过,否则验证失败.
3、基本配置使用
# -*- coding:utf8 -*-
import ldap
from django_auth_ldap.config import LDAPSearch, PosixGroupType AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend', # 配置为先使用LDAP认证,如通过认证则不再使用后面的认证方式
'django.contrib.auth.backends.ModelBackend', # 同时打开本地认证,因为下游系统的权限和组关系需要用到
) #默认登录后打开首页
LOGIN_REDIRECT_URL = '/'
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 关闭流量器不清空session
SESSION_COOKIE_AGE = 60*60*8 # 8小时后session认证过期 base_dn = 'dc=cloud,dc=cn' # 请求的域名后缀为:cloud.cn
AUTH_LDAP_SERVER_URI = 'ldap://ldap-qc.intra.cloud.cn' # LDAP系统的地址及端口号
AUTH_LDAP_BIND_DN = 'cn=cloud,ou=admin,dc=ycloud,dc=cn' # 以admin身份查找用户及相关信息
AUTH_LDAP_BIND_PASSWORD = 'xxxxx' # admin账号的密码
AUTH_LDAP_USER_SEARCH = LDAPSearch('ou=People,%s' % base_dn, ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
# 第一个参数指定查询目录,第三个参数是过滤条件,过滤条件可以很复杂,有需要请查看相关文档.
AUTH_LDAP_ALWAYS_UPDATE_USER = True
# Default is True,是否登录后从ldap同步用户,不进行同步,因为下游的用户表是什么样的不能确定,只能确定它也使用邮箱前缀 '''一些其他配置'''
# 下游系统不从ldap同步group staff/superuser相关,但需要从ldap验证用户是否离职
# AUTH_LDAP_GROUP_SEARCH = LDAPSearch('ou=Group,dc=ldap,dc=ssotest,dc=net', ldap.SCOPE_SUBTREE, "(objectClass=posixGroup)")
# AUTH_LDAP_GROUP_TYPE = PosixGroupType(name_attr="cn")
# AUTH_LDAP_REQUIRE_GROUP = u"cn=员工,ou=Group,dc=ldap,dc=ssotest,dc=net"
# AUTH_LDAP_DENY_GROUP = u"cn=黑名单,ou=Group,dc=ldap,dc=ssotest,dc=net"
# AUTH_LDAP_FIND_GROUP_PERMS = True # django从ldap的组权限中获取权限,这种方式,django自身不创建组,每次请求都调用ldap,下游子系统,我们并不需要让他同步ldap里的"员工","管理员"这种表,所以不用mirror_groups
# AUTH_LDAP_CACHE_GROUPS = True # 如打开FIND_GROUP_PERMS后,才生效,对组关系进行缓存,不用每次请求都调用ldap
# AUTH_LDAP_GROUP_CACHE_TIMEOUT = 600
# ### ldap 配置部分END ### #
settings.py中配置ldap
from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.Login.as_view()),
url(r'^home/', views.home, name='home'),
app01/urls.py
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8">
<title>登录</title>
<link rel="stylesheet" href="/static/AdminLTE/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/static/AdminLTE/fonts/font-awesome.min.css">
<link rel="stylesheet" href="/static/AdminLTE/ionicons/ionicons.css">
<link rel="stylesheet" href="/static/AdminLTE/dist/css/AdminLTE.css">
<style>
.errorlist {
color: red;
}
</style>
</head> <body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<b>运维工单·平台</b>
</div>
<div class="login-box-body">
{% if form.errors %}
<p class="errorlist">你输入的用户名密码不正确!!</p>
{% endif %}
<form action="" method="POST">{% csrf_token %}
<div class="form-group has-feedback">
<input type="text" class="form-control" name="username" placeholder="用户名" required>
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" class="form-control" name="password" placeholder="密码" required>
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<button class="btn btn-primary btn-block btn-flat" type="submit">登陆</button>
</form>
<br> </div>
</div>
</body>
</html>
login.html
1.2 在django项目中使用
# -*- coding:utf8 -*-
import ldap
from django_auth_ldap.config import LDAPSearch, PosixGroupType AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend', # 配置为先使用LDAP认证,如通过认证则不再使用后面的认证方式
'django.contrib.auth.backends.ModelBackend', # 同时打开本地认证,因为下游系统的权限和组关系需要用到
) #默认登录后打开首页
LOGIN_REDIRECT_URL = '/'
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 关闭流量器不清空session
SESSION_COOKIE_AGE = 60*60*8 # 8小时后session认证过期 base_dn = 'dc=cloud,dc=cn' # 请求的域名后缀为:cloud.cn
AUTH_LDAP_SERVER_URI = 'ldap://ldap-qc.intra.cloud.cn' # LDAP系统的地址及端口号
AUTH_LDAP_BIND_DN = 'cn=cloud,ou=admin,dc=cloud,dc=cn' # 以admin身份查找用户及相关信息
AUTH_LDAP_BIND_PASSWORD = 'xxxxx' # admin账号的密码
AUTH_LDAP_USER_SEARCH = LDAPSearch('ou=People,%s' % base_dn, ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
# 第一个参数指定查询目录,第三个参数是过滤条件,过滤条件可以很复杂,有需要请查看相关文档.
AUTH_LDAP_ALWAYS_UPDATE_USER = True
# Default is True,是否登录后从ldap同步用户,不进行同步,因为下游的用户表是什么样的不能确定,只能确定它也使用邮箱前缀 '''一些其他配置'''
# 下游系统不从ldap同步group staff/superuser相关,但需要从ldap验证用户是否离职
# AUTH_LDAP_GROUP_SEARCH = LDAPSearch('ou=Group,dc=ldap,dc=ssotest,dc=net', ldap.SCOPE_SUBTREE, "(objectClass=posixGroup)")
# AUTH_LDAP_GROUP_TYPE = PosixGroupType(name_attr="cn")
# AUTH_LDAP_REQUIRE_GROUP = u"cn=员工,ou=Group,dc=ldap,dc=ssotest,dc=net"
# AUTH_LDAP_DENY_GROUP = u"cn=黑名单,ou=Group,dc=ldap,dc=ssotest,dc=net"
# AUTH_LDAP_FIND_GROUP_PERMS = True # django从ldap的组权限中获取权限,这种方式,django自身不创建组,每次请求都调用ldap,下游子系统,我们并不需要让他同步ldap里的"员工","管理员"这种表,所以不用mirror_groups
# AUTH_LDAP_CACHE_GROUPS = True # 如打开FIND_GROUP_PERMS后,才生效,对组关系进行缓存,不用每次请求都调用ldap
# AUTH_LDAP_GROUP_CACHE_TIMEOUT = 600
# ### ldap 配置部分END ### #
settings.py中配置ldap
from django.conf.urls import url
from django.contrib import admin
from app01 import views
from django.contrib.auth.views import login, logout urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.Login.as_view()),
url(r'^home/', views.home, name='home'),
url(r'^$',views.index),
url(r'^ac_logout/?$', views.logout_view, name="account_logout"),
url(r'^change_passwd/?$', views.change_pass, name="change_passwd"),
]
urls.py
# # -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render,HttpResponse,redirect
from django.contrib.auth.views import LoginView
from django.contrib.auth import login as auth_login
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.contrib.auth.forms import PasswordChangeForm #1、登录:优先使用ldap认证,settings中配置了
class Login(LoginView):
template_name = 'login.html'
def form_valid(self, form):
auth_login(self.request, form.get_user())
return super(Login, self).form_valid(form) def get_context_data(self, **kwargs):
context = super(Login,self).get_context_data(**kwargs)
return context #2、注销
def logout_view(request):
logout(request)
return redirect('/login') #3、修改密码:可以修改本地密码,不是修改ldap密码
@login_required(login_url='/login')
def change_pass(request):
form = PasswordChangeForm(user=request.user)
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
form.save()
return redirect('/')
return render(request, template_name='change_pass.html', context={'form': form, 'username': request.user.username}) #4、index首页:登陆后默认返回此页面
@login_required(login_url='/login')
def index(request):
return render(request, 'index.html') #5、home页面:只有登录才返回,否则返回到login页面
@login_required(login_url='/login')
def home(request):
return HttpResponse('home')
app01/views.py
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8">
<title>登录</title>
<link rel="stylesheet" href="/static/AdminLTE/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/static/AdminLTE/fonts/font-awesome.min.css">
<link rel="stylesheet" href="/static/AdminLTE/ionicons/ionicons.css">
<link rel="stylesheet" href="/static/AdminLTE/dist/css/AdminLTE.css">
<style>
.errorlist {
color: red;
}
</style>
</head> <body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<b>运维工单·平台</b>
</div>
<div class="login-box-body">
{% if form.errors %}
<p class="errorlist">你输入的用户名密码不正确!!</p>
{% endif %}
<form action="" method="POST">{% csrf_token %}
<div class="form-group has-feedback">
<input type="text" class="form-control" name="username" placeholder="用户名" required>
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" class="form-control" name="password" placeholder="密码" required>
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<button class="btn btn-primary btn-block btn-flat" type="submit">登陆</button>
</form>
<br> </div>
</div>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>index</h1>
<p><a href="{% url 'account_logout' %}">注销</a></p>
<p><a href="{% url 'home' %}">home页面</a></p>
<p><a href="{% url 'change_passwd' %}">修改密码</a></p> <div>
<h2>展示用户额外信息</h2>
<p>{{ request.user }}</p>
<p>{{ request.user.userprofile.zhname }}</p>
</div>
</body>
</html>
index.html
<h1>更改密码</h1>
{% block main_content %}
<div class="col-md-6">
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">{{ request.user.username }}修改密码</h3>
</div>
<form class="form-horizontal" action="" method="post">
{% csrf_token %}
<div class="box-body">
<div class="form-group">
<label for="id_old_password" class="col-sm-3 control-label">旧密码:</label>
<div class="col-sm-9">
{{ form.old_password.errors }}
{{ form.old_password }}
</div>
</div>
<div class="form-group">
<label for="id_new_password1" class="col-sm-3 control-label">新密码:</label>
<div class="col-sm-9">
{{ form.new_password1.errors }}
{{ form.new_password1 }}
</div>
</div>
<div class="form-group">
<label for="id_new_password2" class="col-sm-3 control-label">新密码确认:</label>
<div class="col-sm-9">
{{ form.new_password2.errors }}
{{ form.new_password2 }}
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-default">提交</button>
<button type="reset" class="btn btn-info pull-right">重置</button>
</div>
<!-- /.box-footer -->
</form>
</div>
</div>
{% endblock %}
change_pass.html
# -*- coding: utf-8 -*-
from __future__ import unicode_literals from django.db import models
from django.contrib.auth.models import User class UserProfile(models.Model):
user = models.OneToOneField(User,verbose_name='用户名')
zhname = models.CharField(max_length=50,verbose_name='姓名',blank=True,null=True)
app01/models.py 中使用UserProfile表为User表添加额外信息
1、页面效果

2、说明
1. 我们只需要在settings中配置使用ldap认证后,django就可以利用ldap进行认证了
2、然后我们利用django内置模块 LoginView 定义登录界面视图函数 Login(LoginView) 来验证ldap身份
3、需要身份认证的视图函数仅需使用django的 login_required 模块进行装饰即可:@login_required(login_url='/login')
07: Django 使用ldap登录、注销等的更多相关文章
- Django框架基于session的登录/注销实现
博主最近想基于Django框架开发一个测试平台,第一版先实现查看下载自动化的测试报告文件 第一步:前端框架 网上选择一款开源boostrap的前端框架 AdminLTE,这里给个链接 https:/ ...
- Django项目:CRM(客户关系管理系统)--47--38PerfectCRM实现全局账号登录注销02
图片另存为 16*16 名字修改为 global_logo.jpg /*! *bootstrap.js * * Bootstrap v3.3.7 (http://getbootstrap ...
- Django项目:CRM(客户关系管理系统)--46--38PerfectCRM实现全局账号登录注销01
python.exe manage.py startapp gbacc #urls.py """PerfectCRM URL Configuration The `url ...
- django用户认证系统——注销和页面跳转5
当用户想切换登录账号,或者想退出登录状态时,这时候就需要注销已登录的账号.现在我们来为网站添加注销登录的功能,这个功能 Django 也已经为我们提供,我们只需做一点简单配置. 注销登录 注销登录的视 ...
- Django之auth登录认证
前言:我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个完美主义者的 ...
- 传智播客JavaWeb day07、day08-自定义标签(传统标签和简单标签)、mvc设计模式、用户注册登录注销
第七天的课程主要是讲了自定义标签.简单介绍了mvc设计模式.然后做了案例 1. 自定义标签 1.1 为什么要有自定义标签 前面所说的EL.JSTL等技术都是为了提高jsp的可读性.可维护性.方便性而取 ...
- Django:用户登录实例
Django:用户登录实例 一.源代码 1,login.html代码(登录界面): <!DOCTYPE html> <html lang="zh-CN"> ...
- Django 07 Django模型基础2 (常用查询和多表关联)
Django 07 Django模型基础2 (常用查询和多表关联) 一.常用查询 #查找数据 def search_user(request): #获取 rs = User.objects.first ...
- 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)
前言: shiro因为其简单.可靠.实现方便而成为现在最常用的安全框架,那么这篇文章除了会用简洁明了的方式讲一下基于spring的shiro详细配置和登录注销功能使用之外,也会根据惯例在文章最后总结一 ...
随机推荐
- 三种邻接表存图模板:vector邻接表、数组邻接表、链式前向星
vector邻接表: ; struct Edge{ int u,v,w; Edge(int _u=0,int _v=0,int _w=0){u=_u,v=_v,w=_w;} }; vector< ...
- CCCC L2-008. 最长对称子串
https://www.patest.cn/contests/gplt/L2-008 题解:想法是扫一遍string,将每一个s[i]作为对称轴,写一个判定函数:不断向两边延伸直到不是回文串为止. ...
- Python正则表达式匹配猫眼电影HTML信息
爬虫项目爬取猫眼电影TOP100电影信息 项目内容来自:https://github.com/Germey/MaoYan/blob/master/spider.py 由于其中需要爬取的包含电影名字.电 ...
- wampserver 权限配置
当你按照网上以前介绍的wamp配制方法,安装好wamp后.本地的locallhost和127.0.0.1一切都正常,他们都能对你本地的网页文件进行访问.这里说一说,手机借助wamp访问本地文件的方法. ...
- python3学习笔记(9)_closure
#python 学习笔记 2017/07/13 # !/usr/bin/env python3 # -*- conding:utf-8 -*- #从高阶函数的定义,我们可以知道,把函数作为参数的函数, ...
- 构建更好的客户端 JavaScript 应用
你可能注意到了,最近的一段时间越来越多的Web应用有变复杂的趋势,重心从服务端慢慢向着客户端转移. 这是个正常的趋势么?我不知道.支持和反对者的讨论就像是在讨论复活者和圣诞节哪一个更好一样; 很难说哪 ...
- 洛谷P3953 逛公园 [noip2017] 图论+dp
正解:图论(最短路)+dp(记忆化搜索) 解题报告: 这题真的是个好东西! 做了这题我才发现我的dij一直是错的...但是我以前用dij做的题居然都A了?什么玄学事件啊...我哭了TT 不过其实感觉还 ...
- web 开发常见问题--GET POST 区别
首先,get和post是什么? --两种 HTTP 请求方法:GET 和 POST HTTP Request Methods GET.POST 专业名称是 HTTP Request Methods.但 ...
- 常见浏览器兼容性问题与解决方案css篇
浏览器兼容问题一:不同浏览器的标签默认的外补丁和内补丁不同 问题症状:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大. 碰到频率:100% 解决方案:CSS里 ...
- 【查阅】mysql系统视图查看
[1]查看表大小 SELECT CONCAT(table_schema,'.',table_name) AS 'Table Name', table_rows AS 'Number of Rows', ...