我正在使用该ldap3
模块并尝试创建一个简单的 Web 应用程序来搜索 ldap 服务器中的用户。用户(通常是帮助台人员,进行搜索)必须登录并输入搜索的用户。到目前为止的代码创建/绑定到 ldap 服务器,并且在找到搜索到的用户后,将显示一个不同的页面,显示用户的凭据。到目前为止,一切都很好。
在显示凭据的页面上,有一个搜索框,以便用户可以再次搜索另一个用户。我现在遇到的问题是如何通过 ldap 保持登录状态,以便用户只需要输入搜索到的用户(而不是再次输入他的用户名和密码)。我在想我需要解析conn
返回中的对象,但这似乎有点笨拙。这是我的代码:
视图.py
def ldap_authentication(request):
if request.POST:
username = request.POST['username']
LDAP_MODIFY_PASS = request.POST['password']
searchFilter = request.POST['searchUser']
LDAP_AUTH_SEARCH_DN = '{}\\{}'.format(settings.DOMAIN_NAME, username)
conn = ldap_connect(request, un=LDAP_AUTH_SEARCH_DN, pw=LDAP_MODIFY_PASS)
attributes_list_keys = ['mail', 'givenName', 'employeeID',
'department', 'telephoneNumber', 'st', 'cn', 'l', 'title']
conn.search(
search_base=settings.LDAP_AUTH_SEARCH_BASE,
search_filter= '(cn={})'.format(searchFilter),
search_scope=SUBTREE,
attributes = attributes_list_keys
)
entry = conn.entries[0]
attributes_split = list(entry._attributes.values())
attr_keys = []
attr_values = []
for i in attributes_split:
attr_keys.append(i.key)
attr_values.append(i.value)
attributes = zip(attr_keys, attr_values)
return render(request, 'search_page.html', {'attributes':attributes})
return render(request, 'login.html')
def ldap_connect(request, un=None, pw=None):
try:
# Define the server
server = Server(settings.LDAP_SERVER, get_info=ALL)
# Connection and Bind operation
conn = Connection(server, user=un, password=pw, \
auto_bind=True,check_names=True)
conn.start_tls() # Session now on a secure channel.
return conn
except LDAPBindError as e:
print ("LDAPBindError, credentials incorrect: {0}".format(e))
logger.debug("LDAPBindError, credentials incorrect: {0}".format(e))
sys.exit(1)
except LDAPSocketOpenError as e:
print ("LDAPSocketOpenError, LDAP Server connection error: {0}".format(e))
logger.debug("LDAPSocketOpenError, LDAP Server connection error: {0}".format(e))
sys.exit(1)
def search_ldap_user(request):
if request.POST:
searchFilter = request.POST['searchUser']
print ("searchFilter_POST: {0}".format(searchFilter))
return render(request, 'login.html')
search_page.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="page-header">
<h2>LDAP Search Page</h2>
</div>
<p><p>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<table class="table table-striped table-condensed"
id="orders_open">
<thead>
<tr>
<th>Attribute in LDAP</th>
<th>Value</th>
</tr>
</thead>
{% for item1, item2 in attributes %}
<tr>
<td>{{ item1 }}</td>
<td>{{ item2 }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
<br><br><br><br>
<form method='post' action="{% url 'searchAnother' %}" class="form-signin">
{% csrf_token %}
<input type="text" class="form-control" name="searchUser"
placeholder="Search User" required=""/>
<button type="submit">Search</button>
</form>
<form method='post' action="" class="form-signin">{% csrf_token %}
<br>
<a href="{% url 'logout' %}" class="btn btn-lg btn-danger btn-
block">LogOut</a>
</form>
{% endblock content %}
登录.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="page-header">
<h2>Welcome to LDAP Search. Please enter your credentials.</h2>
</div>
<div class="wrapper">
<form method='post' action="" class="form-signin">{% csrf_token %}
<h3 class="form-signin-heading">Please login</h3>
<input type="text" class="form-control" name="username"
placeholder="Username" required="" autofocus=""/>
<br>
<input type="password" class="form-control" name="password"
placeholder="Password" required=""/>
<br>
<input type="text" class="form-control" name="searchUser"
placeholder="Search User" required=""/>
<br>
<button class="btn btn-lg btn-primary btn-block" type="submit">Login</button>
</form>
</div>
{% endblock content %}
我认为问题在于以某种方式将search_ldap_user
myviews.py
中的函数与search_page.html
通过 conn 对象联系起来,但似乎不清楚我该如何做到这一点。有没有人使用 ldap 进行身份验证的类似经验?
更新
所以我切换到django_python3_ldap
图书馆,有以下内容:
设置.py
DOMAIN_NAME = 'OurDomain'
LDAP_AUTH_URL = 'ldap://10.254.9.31:389'
LDAP_AUTH_USE_TLS = False
LDAP_AUTH_SEARCH_BASE = 'ou=company-Konzern, dc=ourdomain, dc=de'
LDAP_AUTH_OBJECT_CLASS = 'inetOrgPerson'
LDAP_AUTH_USER_FIELDS = {
"username": "cn",
"first_name": "givenName",
"last_name": "sn",
"email": "mail",
}
# More info: https://github.com/etianen/django-python3-ldap
#LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",)
LDAP_AUTH_USER_LOOKUP_FIELDS = ("cn",)
LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data"
LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations"
LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters"
LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_openldap"
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = 'OurDomain'
#LDAP_AUTH_CONNECTION_USERNAME = 'e123456'
LDAP_AUTH_CONNECTION_USERNAME = 'OurDomain\e123456'
LDAP_AUTH_CONNECTION_PASSWORD = 'abcdefghi'
LDAP_AUTH_CONNECT_TIMEOUT = None
LDAP_AUTH_RECEIVE_TIMEOUT = None
AUTHENTICATION_BACKENDS = (
'django_python3_ldap.auth.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_python3_ldap'
]
视图.py
def ldap_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
print ("username: {0}".format(username))
print ("password: {0}".format(password))
ldap_auth_search_dn = '{}\\{}'.format(settings.DOMAIN_NAME, username)
print ("ldap_auth_search_dn: {0}".format(ldap_auth_search_dn))
user = authenticate(username=username, password=password)
#user = authenticate(username=ldap_auth_search_dn, password=password)
print ("user: {0}".format(user))
if user and user.is_active:
print ("user.is_active!!")
login(request, user, backend='django_python3_ldap.auth.LDAPBackend')
return render(request, 'login_ldap.html')
正如您从注释掉的行中看到的那样,我在 settings.py 中尝试了各种配置排列,但仍有一些我不清楚的问题:
- 这在 settings.py: 中是强制性的
LDAP_AUTH_OBJECT_CLASS
吗? - 哪个是正确
LDAP_AUTH_USER_LOOKUP_FIELDS
使用? - 与 2 相同,但对于
LDAP_AUTH_CONNECTION_USERNAME
(这是否应该包括域)?
使用命令时抛出以下错误消息
python ./manage.py ldap_sync_users
错误:
CommandError: Could not connect to LDAP server
当我不使用ldap_sync_users
命令而只是运行服务器时,似乎没有连接,因为user
print 语句中的返回为None
. 我知道连接有效的凭据,因为我之前使用该ldap3
库的代码有效。我唯一能想到的是LDAP_AUTH_SEARCH_BASE
两个库之间的不一样。