如何限制对 Django 管理页面的访问?

问题描述 投票:0回答:7

我需要 Django 管理界面仅可供超级用户和工作人员在生产中访问,并显示所有其他类型的用户(包括未登录时)的 404。这可能吗?如何实现?

python django django-admin
7个回答
22
投票

我最终为它编写了一个中间件:

from django.core.urlresolvers import reverse
from django.http import Http404

class RestrictStaffToAdminMiddleware(object):
    """
    A middleware that restricts staff members access to administration panels.
    """
    def process_request(self, request):
        if request.path.startswith(reverse('admin:index')):
            if request.user.is_authenticated():
                if not request.user.is_staff:
                    raise Http404
            else:
                raise Http404

6
投票

在 url 中使用 AdminSite 类的 admin_view 部分之前,请先覆盖它。

在 admin.py 文件中(如果没有则创建它)添加:

from functools import update_wrapper

from django.http import Http404
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect


def admin_view(view, cacheable=False):
    """
    Overwrite the default admin view to return 404 for not logged in users.
    """
    def inner(request, *args, **kwargs):
        if not request.user.is_active and not request.user.is_staff:
            raise Http404()
        return view(request, *args, **kwargs)

    if not cacheable:
        inner = never_cache(inner)

    # We add csrf_protect here so this function can be used as a utility
    # function for any view, without having to repeat 'csrf_protect'.
    if not getattr(view, 'csrf_exempt', False):
        inner = csrf_protect(inner)

    return update_wrapper(inner, view)

然后在你的urls文件中添加:

from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.views.defaults import page_not_found

from my_project.admin import admin_view
admin.site.admin_view = admin_view

urlpatterns = patterns('',
    url(r'^admin/login/', page_not_found),
    url(r'^admin/', include(admin.site.urls)),
)

当然,如果您仍然希望找到登录名,请删除 url(r'^admin/login/', page_not_found) 行。


1
投票

如果您使用默认的 Django 管理页面,Django 已经具有内置控件来限制对这些页面的访问。用户模型的

is_staff
布尔值控制用户是否有权访问 Django 管理页面。
is_superuser
布尔值控制用户是否拥有所有权限,而无需显式分配它们。但请注意,
is_superuser
不会授予对 Django 管理页面的访问权限;无论
is_staff
的值如何,都必须将
is_superuser
设置为 True,用户才能访问 Django 管理页面。

https://docs.djangoproject.com/en/1.6/ref/contrib/auth/#django.contrib.auth.models.User.is_staff

但是我不知道如果非员工用户尝试访问 Django 管理界面,Django 是否会引发 404 错误。


1
投票

我创建了@ip. 中间件的更新版本。这使用

process_view
直接检查视图是否是管理站点的成员,而不仅仅是检查 URL 是否在管理站点上。如果未经授权的用户尝试访问管理站点,它还会添加警告日志条目,并简化
if
逻辑。这是为 Python 3 和 Django 2 编写的。

from inspect import getmodule
import django.contrib.admin.sites
from django.http import Http404
import logging 

logger = logging.getLogger(__name__)


class RestrictStaffToAdminMiddleware:
    """
    A middleware that restricts staff members access to administration panels.
    """
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        module = getmodule(view_func)
        if (module is django.contrib.admin.sites) and (not request.user.is_staff):
            ip = request.META.get('HTTP_X_REAL_IP', request.META.get('REMOTE_ADDR'))
            ua = request.META.get('HTTP_USER_AGENT')
            logger.warn(f'Non-staff user "{request.user}" attempted to access admin site at "{request.get_full_path()}". UA = "{ua}", IP = "{ip}", Method = {request.method}')
            raise Http404


0
投票

您可以创建自己的 admin_login_required 装饰器。 装饰器应该检查是否存在用户以及用户是否是管理员类型。如果没有用户,或者用户不是管理员,您可以重定向到登录页面或显示一条消息,说明用户未经授权。

这是一个如何为 django 视图编写装饰器的好例子。 http://passingcuriosity.com/2009/writing-view-decorators-for-django/

该页面描述了 anonymous_required 装饰器的示例,其中用户必须是匿名的。 您可以采用该示例并使用我上面提供的规范实现 admin_login_required 装饰器,或者提出您自己的场景。

祝你好运。


0
投票

您可以使用此软件包 django-admin-ip-restrictor 并仅为管理员视图设置 ip 限制。

安装包:

pip install django-admin-ip-restrictor

您的settings.py中的示例

MIDDLEWARE = [
    ...,
admin_ip_restrictor.middleware.AdminIPRestrictorMiddleware

]

RESTRICT_ADMIN=True
ALLOWED_ADMIN_IPS=['127.0.0.1']
ALLOWED_ADMIN_IP_RANGES=['127.0.0.0/24']
RESTRICTED_APP_NAMES=['admin']
TRUST_PRIVATE_IP=True

0
投票

这是有效的@ip代码(确保其在settings.py中间件列表中的身份验证后中间件)

from django.urls import reverse
from django.http import Http404
from django.utils.deprecation import MiddlewareMixin
class RestrictNormalToAdmin(MiddlewareMixin):
    def process_request(self, request):
        if request.path.startswith(reverse('admin:index')):
            if request.user.is_authenticated:
                if not request.user.is_staff:
                    raise Http404
            else:
                raise Http404
© www.soinside.com 2019 - 2024. All rights reserved.