Должны ли » Пользователи` существовать в Django для единого входа?

#python #django #django-rest-framework #django-authentication #django-users

Вопрос:

В принципе, я реализую следующую функциональность, в которой интерфейс будет отправлять подписанные JWTS на серверную часть. Если серверная часть способна декодировать и, следовательно, проверять Токен (т. Е. подпись, утверждения, аудиторию и т. Д.), То она предоставит доступ к защищенным ресурсам API:

введите описание изображения здесь

Теперь пользователи уже существуют в Azure AD (поэтому я не хочу создавать пользователей и управлять ими в базе данных Django). Поэтому, по сути, все, что я хочу сделать, это защитить конечные точки API Django Restful с помощью проверенных маркеров доступа. Я рассматривал пользовательскую аутентификацию (путем расширения rest_framework.authentication.BaseAuthentication ), но, похоже, authenticate метод ожидает, что a User будет сопоставлен (следовательно Users , будет существовать) и возвращен для успешной аутентификации (я бы хотел, чтобы pass проверка JWT прошла успешно или raise Exception произошла ошибка).

Документы Django:

Either way, authenticate() should check the credentials it gets and return a user object that matches those credentials if the credentials are valid. If they’re not valid, it should return None.

Я достиг желаемого потока (т. Е. Без пользователей Django), используя method_decorator , но это не похоже на правильный шаблон для аутентификации:

 class ComponentViewSet(viewsets.ModelViewSet):
    queryset = Component.objects.all()
    serializer_class = ComponentSerializer

    @method_decorator(validate_jwt)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)
 

В документах Django также говорится, что:

The Django admin is tightly coupled to the Django User object. The best way to deal with this is to create a Django User object for each user that exists for your backend (e.g., in your LDAP directory, your external SQL database, etc.).You can either write a script to do this in advance or your authenticate method can do it the first time a user logs in.

Я также выполнил отдельную реализацию пользовательской аутентификации, создав Users метод «на лету» в authenticate соответствии с рекомендациями документации.

Поэтому мой вопрос в том, является ли Users наличие в Django настоятельно рекомендуемым дизайном (или должно быть в соответствии с документами), Даже если у вас есть централизованно управляемая система аутентификации, такая как LDAP/AD и т. Д.? Или также принято не использовать Users модель и использовать какой-либо другой вид реализации (например, декоратор метода, который я использовал), когда вы не собираетесь хранить какую User -либо информацию в бэкэнде, потому что я считаю ее избыточной? Существуют ли какие-либо преимущества дублирования базы данных пользователей в бэкэнде Django, если это настоятельно рекомендуется. И требуются ли этим пользователям также пароли, если они расширяются django.contrib.auth.models.User ?

Ответ №1:

Вместо того, чтобы использовать декоратор для каждого метода, просто создайте свой собственный сервер аутентификации. Когда вызывается представление authenticate() , Django вызывает все бэкэнды, указанные в AUTHENTICATION_BACKENDS , пока один из них не вернется None .

Что касается хранения пользователей, Django по умолчанию предполагает, что вы хотите хранить данные сеанса в бэкэнде, чтобы не требовать входа в систему. Если вас устраивает повторная аутентификация по каждому запросу, вы можете просто вернуть новый экземпляр BaseUser объекта без сохранения в базе данных, хотя другие функции Django могут нарушиться неожиданным образом.

Возможно, вам захочется изучить возможность создания собственной модели пользователя на основе AbstractUser или даже AbstractBaseUser . Если вы не получаете новый токен при каждом запросе, имеет смысл хранить токен в пользовательской модели вместе с when_authenticated time_to_expiry , и т.д.

Новый пользователь ИЛИ возвращающийся пользователь, у которого when_authenticated time_to_expiry < now() есть токен доступа, будет проверен на сервере аутентификации. В случае успеха обновите необходимые поля времени вместе с current_access_token . Последующие запросы в окне обновления просто должны выполнить быструю проверку на равенство, в отличие от другого запроса к серверу.

Это избавит ваш аутентификационный сервер от множества запросов, ускорит ваш API (без проверки подлинности сервера при каждом вызове) и все равно позволит вам использовать некоторые из потрясающих функций, которые Django предоставляет пользователям.