Подтвердить что ты не робот

Пользовательское олицетворение пользователя Django

У меня есть приложение Django. Когда вы входите в систему как пользователь admin, я хочу иметь возможность передавать секретный параметр в URL-адрес и вести себя на всем сайте так, как если бы я был другим пользователем.

Скажем, у меня есть URL /my-profile/, который показывает текущий зарегистрированный профиль пользователя. Я хочу иметь возможность сделать что-то вроде /my-profile/?__user_id=123 и иметь базовое представление, полагая, что я на самом деле являюсь пользователем с ID 123 (таким образом, отображаю этот профиль пользователя).

Зачем мне это нужно?

Просто потому, что намного проще воспроизводить определенные ошибки, которые появляются только в одной учетной записи пользователя.

Мои вопросы:

  • Каким будет самый простой способ реализовать что-то вроде этого?

  • Есть ли какая-либо озабоченность по поводу безопасности, которую я должен иметь в виду при этом? Обратите внимание, что я (очевидно) хочу иметь эту функцию только для пользователей-администраторов, и у наших пользователей-администраторов есть полный доступ к исходному коду, базе данных и т.д., Так что это не действительно "бэкдор"; он просто упрощает доступ к учетной записи пользователя.

4b9b3361

Ответ 1

Я решил это с помощью простого промежуточного программного обеспечения. Он также обрабатывает перенаправления (то есть параметр GET сохраняется во время перенаправления). Вот он:

class ImpersonateMiddleware(object):
    def process_request(self, request):
        if request.user.is_superuser and "__impersonate" in request.GET:
            request.user = models.User.objects.get(id=int(request.GET["__impersonate"]))

    def process_response(self, request, response):
        if request.user.is_superuser and "__impersonate" in request.GET:
            if isinstance(response, http.HttpResponseRedirect):
                location = response["Location"]
                if "?" in location:
                    location += "&"
                else:
                    location += "?"
                location += "__impersonate=%s" % request.GET["__impersonate"]
                response["Location"] = location
        return response

Ответ 2

У меня недостаточно репутации для редактирования или ответа (я думаю), но я обнаружил, что хотя решение ionaut работало в простых случаях, более надежным решением для меня было использование переменной сеанса. Таким образом, даже запросы AJAX подаются правильно, не изменяя URL-адрес запроса, чтобы включить параметр олицетворения GET.

class ImpersonateMiddleware(object):
    def process_request(self, request):
        if request.user.is_superuser and "__impersonate" in request.GET:
            request.session['impersonate_id'] = int(request.GET["__impersonate"])
        elif "__unimpersonate" in request.GET:
            del request.session['impersonate_id']
        if request.user.is_superuser and 'impersonate_id' in request.session:
            request.user = User.objects.get(id=request.session['impersonate_id'])

Использование:

log in: http://localhost/?__impersonate=[USERID]
log out (back to admin): http://localhost/?__unimpersonate=True

Ответ 3

Похоже, что некоторые другие люди столкнулись с этой проблемой и написали повторно используемые приложения, чтобы сделать это, и по крайней мере некоторые из них перечислены в пакетах django страница для переключения пользователей. Наиболее активными в момент написания являются:

  • django-hijack помещает кнопку "hijack" в список пользователей в админе, а также немного вверху страницы, пока вы захватили учетную запись.
  • impostor означает, что вы можете войти в систему с именем пользователя "я как другой" и ваш собственный пароль.
  • django-impersonate устанавливает URL-адреса, чтобы начать выдавать себя за пользователя, останавливаться, искать и т.д.

Ответ 4

Я не вижу, как это дыра в безопасности, больше, чем использование su - someuser как root на машине unix. root или django-admin с доступом root/admin к базе данных могут подделывать что угодно, если захочет. риск только в учетной записи django-admin, взломанной, и в этот момент взломщик может скрыть дорожки, став другим пользователем, а затем фальсифицирует действия как пользователь.

да, его можно назвать бэкдором, но, как говорит ibz, админы имеют доступ к базе данных в любом случае. возможность внесения изменений в базу данных в этом свете также является бэкдором.

Ответ 5

@Charles Offenbacher отвечает за выдачу себя за пользователей, которые не аутентифицируются с помощью токенов. Однако он не будет работать с клиентскими приложениями, использующими аутентификацию по токенам. Чтобы заставить пользователя работать с приложениями с использованием токенов, нужно напрямую настроить заголовок HTTP_AUTHORIZATION в промежуточном программном обеспечении Impersonate. Мой ответ в основном плагиат Чарльза отвечает и добавляет строки для ручной настройки заголовка.

class ImpersonateMiddleware(object):
    def process_request(self, request):
        if request.user.is_superuser and "__impersonate" in request.GET:
            request.session['impersonate_id'] = int(request.GET["__impersonate"])
        elif "__unimpersonate" in request.GET:
            del request.session['impersonate_id']
        if request.user.is_superuser and 'impersonate_id' in request.session:
            request.user = User.objects.get(id=request.session['impersonate_id'])
            # retrieve user token
            token = Token.objects.get(user=request.user)
            # manually set authorization header to user token as it will be set to that of the admin (assuming the admin has one, of course)
            request.META['HTTP_AUTHORIZATION'] = 'Token {0}'.format(token.key)

Ответ 6

Настройте так, чтобы у вас было два разных имени хоста на одном сервере. Если вы делаете это локально, вы можете подключиться к 127.0.0.1 или localhost, например. Ваш браузер увидит это как три разных сайта, и вы можете войти в систему с разными пользователями. То же самое работает для вашего сайта.

Итак, в дополнение к www.mysite.com вы можете настроить test.mysite.com и войти в систему с пользователем там. Я часто настраивал сайты (с Plone), поэтому у меня есть как www.mysite.com, так и admin.mysite.com, и только разрешаю доступ к этим страницам администратора, что означает, что я могу войти на обычный сайт с именем пользователя, которое имеет проблемы.