How do I restrict access to admin pages in Django?

北城余情 提交于 2020-12-28 07:50:20

问题


I need the Django admin interface to be accessible only for superusers and staff when in productions and show a 404 of all other types of users including when not logged in. Is this possible and how?


回答1:


I ended up writing a middleware for it:

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



回答2:


Overwrite the admin_view part of the AdminSite class before using it in the urls.

In admin.py file (create it if you don't have it) add:

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)

and then in your urls file add:

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)),
)

Of course if you still want the login to be found then remove the url(r'^admin/login/', page_not_found) line.




回答3:


I created an updated version of @ip.'s middleware. This uses process_view to directly check if the view is a member of the admin site, rather than just checking if the URL is on the admin site. It also adds a warning log entry if an unauthorized user attempts to access the admin site, and simplifies the if logic. This is written for Python 3 and 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




回答4:


You can create your own admin_login_required decorator. The decorator should check if there is a user and if the user is an admin type. If there is no user, of if the user is not an admin, you can redirect to a login page or display a message saying user is unauthorized.

Here's a good example how to write a decorator for a django view. http://passingcuriosity.com/2009/writing-view-decorators-for-django/

The page described an example of anonymous_required decorator where user has to be anonymous. You can take that example and implement an admin_login_required decorator using the specs I provided above, or come up with your own scenarios.

Good luck.




回答5:


If you're using the default Django admin pages, Django already has built-in control to restrict access to those pages. The is_staff Boolean for a user model controls whether the user has access to the Django admin pages. The is_superuser Boolean controls whether the user has all privileges without explicitly assigning them. Note, however, that is_superuser will not grant access to the Django admin pages; you must set is_staff to True regardless of the value of is_superuser for a user to have access to the Django admin pages.

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

But I don't know if Django will raise a 404 if a non-staff user tries to access the Django admin interface.



来源:https://stackoverflow.com/questions/24559531/how-do-i-restrict-access-to-admin-pages-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!