4

我有 Django 项目,它有两个应用程序 App1 和 App2)每个应用程序只有 1 个视图。. 我的项目使用 django-auth-ldap 连接到 openldap。我有两组(Group1,Group2)。

我在 app1 和 app2 (@login_required) 中的视图之前添加了装饰器,结果如预期的那样,来自 group1 和 group2 的所有用户都将能够登录到这两个应用程序。

我希望能够只允许 group1 仅访问 app1 而 group2 仅访问 app2 。

我尝试了许多代码,但没有人与我一起工作。

这是我的代码:

app1.views.py

from django.shortcuts import render
from django.template import loader
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.contrib.auth import views as auth_views
@login_required(login_url='/accounts/login/')
def index(request):
    #getting our template
    template = loader.get_template('main/index.html')
    #rendering the template in HttpResponse
    return HttpResponse(template.render())

这是我在 settings.py 中的 ldap 设置:

#Generated by 'django-admin startproject' using Django 1.11.


import os
import django



AUTHENTICATION_BACKENDS = ('django_auth_ldap.backend.LDAPBackend',)

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType


AUTH_LDAP_SERVER_URI = "ldap://mydomain.com"

AUTH_LDAP_BIND_DN = "cn=admin,dc=mydomain,dc=com"

AUTH_LDAP_BIND_PASSWORD = "mypass"

AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=ou_org_unit,dc=mydomain,dc=com",
ldap.SCOPE_SUBTREE, "(uid=%(user)s)")

AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=ou_org_unit,cn=group1,cn=group2,dc=mydomain,dc=com",
    ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)

AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()

AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail"
}

AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600
4

2 回答 2

4

首先,我将一个属性映射到指定用户所在组的用户对象:

AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
    "ldap_group": "cn"   # not 100% sure if this is what's required, just guessing
}

然后制作一个装饰器user_passes_test

from django.contrib.auth.decorators import user_passes_test

def ldap_group_required(group_name):
    """
    Checks if a user is in the specified LDAP group.
    """
    return user_passes_test(
        lambda u: hasattr(u, 'ldap_group') and u.ldap_group == group_name,
        login_url='/accounts/login/'
    )

在这样的视图上使用它:

@ldap_group_required('group1')
def index(request):
    #getting our template
    template = loader.get_template('main/index.html')
    #rendering the template in HttpResponse
    return HttpResponse(template.render())

如果您查看源代码,这就是有效的login_required工作方式。

于 2017-09-20T01:26:41.367 回答
3

我个人会推荐一种稍微不同的方法,使用Django 的内置权限

您可以做的是创建自定义权限,例如,can_access_app1can_access_app2。然后,由于 django-auth-ldap 会自动为您将所有组复制到 Django 数据库中,然后您可以将这些权限分配给适当的组。

现在您的组及其各自的权限已设置完毕,您可以适当地装饰您的视图。例如:

# app1/views.py
from django.contrib.auth.decorators import permission_required
from django.http import HttpResponse
from django.shortcuts import render
from django.template import loader

@permission_required('app1.can_access_app1')
def index(request):
    #getting our template
    template = loader.get_template('main/index.html')
    #rendering the template in HttpResponse
    return HttpResponse(template.render())

这种方法有据可查,不会引入任何必须操纵用户对象的特殊技巧,并且还具有额外的优势,即如果您想授予特殊访问权限,您也可以将这些权限分配给个人。此外,任何超级用户帐户都将自动拥有这两种权限,无需额外努力!

于 2017-09-28T16:01:27.310 回答