在Django后台使用LDAP配置进行身份验证

5 投票
2 回答
5743 浏览
提问于 2025-04-18 18:02

我正在开发一个Django应用,需要直接支持LDAP认证,以便能登录到默认的管理页面。
我已经集成了django-auth-ldap,并按照文档的指导进行配置,直到我能理解为止。
我已经使用OpenLDAP配置了一个本地LDAP服务器,并且用php图形界面进行管理(我也能使用ldif文件进行配置)。当我尝试登录管理页面时,Django能够找到本地服务器和里面的用户对象,并且能识别用户属于哪个组。尽管如此,我还是无法登录。出现的错误信息是:

[21/Aug/2014 11:06:53] "GET /admin/ HTTP/1.1" 200 1870
search_s('ou=users,dc=whiteqube', 2, '(cn=%(user)s)') 返回了 1 个对象: cn=sonia,ou=users,dc=whiteqube
DEBUG:django_auth_ldap:search_s('ou=users,dc=whiteqube', 2, '(cn=%(user)s)') 返回了 1 个对象: cn=sonia,ou=users,dc=whiteqube
sonia的认证失败
DEBUG:django_auth_ldap:sonia的认证失败
[21/Aug/2014 11:06:56] "POST /admin/ HTTP/1.1" 200 2046

在管理界面中,登录总是失败。
我的settings.py文件内容如下:

# - - - - LDAP CONFIGURATION - - - - #
#
# Importing ldap libraries and applications
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, PosixGroupType

# ...connecting to ldap server (local environment uses IP)
AUTH_LDAP_SERVER_URI = "ldap://10.0.2.15"

# ...account to enter into ldap server (anonymous is not always allowed)
#AUTH_LDAP_BIND_DN = "cn=admin,dc=whiteqube"
#AUTH_LDAP_BIND_PASSWORD = "root"

# ...path where to start to search groups
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=groups,dc=whiteqube",
                                    ldap.SCOPE_SUBTREE, # allow searching from current node to all nodes below
                                    "(objectClass=posixGroup)" # type of object
)
AUTH_LDAP_GROUP_TYPE = PosixGroupType() # a posixGroup is identified by the keyword "cn" into ldap server

# ...associations between ldap and django groups
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
    "is_active": "cn=active,ou=groups,dc=whiteqube",
    "is_staff": "cn=staff,ou=groups,dc=whiteqube",
    "is_superuser": "cn=superuser,ou=groups,dc=whiteqube"
}
AUTH_LDAP_PROFILE_FLAGS_BY_GROUPS = {
    "is_awesome": ["cn=awesome,ou=groups,dc=whiteqube"]
}


# ...node where to start to search users
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=whiteqube",
                                   ldap.SCOPE_SUBTREE, # allow searching from current node to all nodes below
                                   "(cn=%(user)s)"
                                   #"(objectClass=posixAccount)"
                                   #"(objectClass=inetOrgPerson)"
)
# Keep ModelBackend around for per-user permissions and maybe a local
# superuser.
AUTHENTICATION_BACKENDS = (
    'django_auth_ldap.backend.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

# Enable debug for ldap server connection
logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
# - - - - END  LDAP CONFIGURATION - - - - #

我的LDAP中包含这些对象:

  • ou=groups,dc=whitecube
    • cn=superuser,ou=groups,dc=whiteqube
    • cn=staff,ou=groups,dc=whiteqube
  • ou=users,dc=whiteqube
    • cn=sonia,ou=users,dc=whiteqube

其中“groups”和“users”是组织单位,"staff"和"superuser"是用户组,"sonia"是一个用户账户。
可以查看下面的图片:

LDAP Tree
我确信LDAP对象的配置是正确的,因为Django的调试信息能识别用户的组依赖关系。

补充说明:我能使用Django本地账户登录管理界面。

我哪里出错了?是否还有其他我遗漏的属性配置?

2 个回答

0

其实我已经解决了关于LDAP对象的一些问题。
我在settings.py文件里添加了一些内容,并且改变了LDAP树的结构(下面有图片链接)。
现在,如果我用LDAP用户的信息登录,程序会在Django的用户表里添加一行记录。查看Django数据库时,我发现Django管理员无法读取用户密码,但django_auth_ldap的文档说明这是正常的。

不过,我还是无法登录。
我发现的新错误是:

[26/Aug/2014 09:42:15] "GET /admin/ HTTP/1.1" 200 1870
search_s('ou=users,dc=whiteqube', 2, '(uid=%(user)s)') returned 1 objects: cn=marco rossi,ou=users,dc=whiteqube
DEBUG:django_auth_ldap:search_s('ou=users,dc=whiteqube', 2, '(uid=%(user)s)') returned 1 objects: cn=marco rossi,ou=users,dc=whiteqube
cn=marco rossi,ou=users,dc=whiteqube is a member of cn=enabled,ou=groups,dc=whiteqube
DEBUG:django_auth_ldap:cn=marco rossi,ou=users,dc=whiteqube is a member of cn=enabled,ou=groups,dc=whiteqube
cn=marco rossi,ou=users,dc=whiteqube is not a member of cn=disabled,ou=groups,dc=whiteqube
DEBUG:django_auth_ldap:cn=marco rossi,ou=users,dc=whiteqube is not a member of cn=disabled,ou=groups,dc=whiteqube
Populating Django user mrossi
DEBUG:django_auth_ldap:Populating Django user mrossi
cn=marco rossi,ou=users,dc=whiteqube is a member of cn=superuser,ou=groups,dc=whiteqube
DEBUG:django_auth_ldap:cn=marco rossi,ou=users,dc=whiteqube is a member of cn=superuser,ou=groups,dc=whiteqube
cn=marco rossi,ou=users,dc=whiteqube is not a member of cn=staff,ou=groups,dc=whiteqube
DEBUG:django_auth_ldap:cn=marco rossi,ou=users,dc=whiteqube is not a member of cn=staff,ou=groups,dc=whiteqube
cn=marco rossi,ou=users,dc=whiteqube is a member of cn=active,ou=groups,dc=whiteqube
DEBUG:django_auth_ldap:cn=marco rossi,ou=users,dc=whiteqube is a member of cn=active,ou=groups,dc=whiteqube
/home/andrea/PycharmProjects/wq_asja_gateway_v1/env/local/lib/python2.7/site-packages/django_auth_ldap/backend.py:590: DeprecationWarning: The use of AUTH_PROFILE_MODULE to define user profiles has been deprecated.
  profile = self._user.get_profile()

WARNING:py.warnings:/home/andrea/PycharmProjects/wq_asja_gateway_v1/env/local/lib/python2.7/site-packages/django_auth_ldap/backend.py:590: DeprecationWarning: The use of AUTH_PROFILE_MODULE to define user profiles has been deprecated.
  profile = self._user.get_profile()

Django user mrossi does not have a profile to populate
DEBUG:django_auth_ldap:Django user mrossi does not have a profile to populate

我新的settings.py配置如下:

#  #  #  #  #  #  #  #  #  #  #  #  #  #  #
# - - - - LDAP CONFIGURATION - - - - #
#
# Importing ldap libraries and applications
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, PosixGroupType

# ...connecting to ldap server (local environment uses IP)
AUTH_LDAP_GLOBAL_OPTIONS = {
    ldap.OPT_X_TLS_REQUIRE_CERT: False,
    ldap.OPT_REFERRALS: False
}
AUTH_LDAP_SERVER_URI = "ldap://10.0.2.15"

# ...account to enter into ldap server (anonymous is not always allowed)
AUTH_LDAP_BIND_DN = "cn=admin,dc=whiteqube"
AUTH_LDAP_BIND_PASSWORD = "root"

# ...node where to start to search users
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=whiteqube",
                                   ldap.SCOPE_SUBTREE,  # allow searching from current node to all nodes below
                                   "(uid=%(user)s)"
                                   #"(objectClass=posixAccount)"
                                   #"(objectClass=simpleSecurityObject)"
)

# ...path where to start to search groups
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=groups,dc=whiteqube",
                                    ldap.SCOPE_SUBTREE,  # allow searching from current node to all nodes below
                                    "(objectClass=posixGroup)"  # type of object
)
AUTH_LDAP_GROUP_TYPE = PosixGroupType(name_attr="cn")  # a posixGroup is identified by the keyword "cn" into ldap server

# ...simple group restrictions
AUTH_LDAP_REQUIRE_GROUP = "cn=enabled,ou=groups,dc=whiteqube"
AUTH_LDAP_DENY_GROUP = "cn=disabled,ou=groups,dc=whiteqube"

# ...populate the Django user from the LDAP directory.
AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
    "username": "uid",
    "password": "userPassword",
}
AUTH_LDAP_PROFILE_ATTR_MAP = {
    "home_directory": "homeDirectory"
}

# ...associations between ldap and django groups
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
    "is_active": "cn=active,ou=groups,dc=whiteqube",
    "is_staff": "cn=staff,ou=groups,dc=whiteqube",
    "is_superuser": "cn=superuser,ou=groups,dc=whiteqube"
}
AUTH_LDAP_PROFILE_FLAGS_BY_GROUPS = {
    "is_awesome": ["cn=awesome,ou=groups,dc=whiteqube"]
}

# ...use LDAP group membership to calculate permission
AUTH_LDAP_FIND_GROUP_PERMS = True

# Keep ModelBackend around for per-user permissions and maybe a local
# superuser.
AUTHENTICATION_BACKENDS = (
    'django_auth_ldap.backend.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

# Enable debug for ldap server connection
logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
# - - - - END  LDAP CONFIGURATION - - - - #
#  #  #  #  #  #  #  #  #  #  #  #  #  #  #

LDAP树 ...其中:

  • cn=marco rossi(我用来登录的账户)是一个posixAccount,属于cn=superuser和cn=enabled这两个posixGroup。

有没有什么建议可以继续进行?

2

我终于搞定了!

调试:一个用户必须属于所有组(活跃组、员工组、超级用户组),才能登录管理界面,至少需要创建一个新的个人组。

我在最后一篇帖子中提到的settings.py和LDAP树的配置是正确的,所以你可以继续参考如何创建你的LDAP并在你的django应用中实现。记住:如果你使用的是默认组,必须把用户添加到所有组里,才能允许他们登录管理后台。

谢谢,再见!

撰写回答