Реализация ролевого управления доступом в Django
Управление доступом является важным компонентом любого приложения, требующего обеспечения безопасности данных, конфиденциальности и привилегированного доступа. Цель управления доступом в приложении - ограничить возможности каждого пользователя.
Существует множество моделей управления доступом, однако в данном руководстве мы сосредоточимся на управлении доступом на основе ролей (RBAC) и способах его реализации в Django.
Мы будем использовать встроенную в Django систему аутентификации для разрешения (или запрета) пользователям доступа к ресурсам или выполнения действий в зависимости от прав, связанных с назначенными им ролями.
Необходимые условия
Для того чтобы ознакомиться с этой статьей, необходимо выполнить следующие требования:
- Иметь знание Python и Django
- Установить Python 3.7 или выше
Обзор аутентификации и авторизации в Django
Django, являясь фреймворком высокого уровня на языке Python, оснащен системой аутентификации.
Эту систему аутентификации принято называть системой аутентификации и авторизации. Это означает, что мы можем использовать встроенную в Django систему аутентификации как для аутентификации (идентификации пользователя), так и для авторизации (предоставления прав доступа).
Ниже перечислены компоненты или модели встроенной системы аутентификации, которые могут быть использованы для реализации RBAC:
- User (Пользователь): Здесь моделируются пользователи приложения.
- Group (Группа): Это модель группы пользователей в приложении. То есть пользователи могут быть разделены на различные группы. В нашей реализации RBAC мы будем использовать эту модель (модель группы) для ролей.
- Permission (Разрешение): Здесь моделируются действия, которые пользователи могут выполнять в приложении, что позволяет точно контролировать права доступа.
Более подробно о каждом из этих компонентов мы расскажем в разделе " Ознакомление".
Ознакомление с реализацией RBAC
Простой пример
Для того чтобы изучить реализацию RBAC, реализуем ее для системы управления школой.
В системе должны существовать следующие роли:
- Студент (Student) - может просматривать свои записи
- Преподаватель (Teacher) - может создавать, обновлять, просматривать и удалять записи о студентах.
- Директор (Principal) - может создавать, читать, обновлять и удалять пользователей и обладает всеми правами на записи учащихся.
В данном примере ресурсом или данными, к которым мы будем ограничивать доступ, является запись оценки студента.
User, Group, и Permission
Как уже упоминалось, система аутентификации предоставляет модель User. Важно знать, что система аутентификации собрана в виде приложения в django.contrib.auth
. Это приложение содержит основную функциональность и необходимые модели.
Система аутентификации доступна по умолчанию в каждом проекте, созданном с помощью команды django-admin startproject
. В той мере, в какой django.contrib.auth
существует в константах INSTALLED_APPS
в файле settings.py
проекта.
Выполнение команды python manage.py migrate
приведет к созданию таблиц для моделей баз данных по умолчанию. Следовательно, пользователь, группа и разрешение теперь будут доступны.
Примечание: Между пользователем и разрешением, а также между группой и разрешением существует отношение "многие-ко-многим".
Сайт администратора Django
Для того чтобы создавать объекты в интерактивном режиме, создадим суперпользователя, который будет иметь доступ к панели администратора Django.
- Выполните команду
python manage.py createsuperuser
- Перейдите на сайт http://127.0.0.1:8000/admin/ и войдите в систему.
Запись оценок студентов
Для создания модели записи оценки студента выполним следующие действия.
- Создайте приложение с именем
record
, выполнив командуpython manage.py startapp record
. - Скопируйте приведенный ниже код в файл
models.py
в приложениеrecord
.
from django.db import models
from django.contrib.auth.models import User
class StudentAssessmentRecord(models.Model):
student = models.ForeignKey(User, on_delete=models.CASCADE)
score = models.IntegerField()
def __str__(self):
return f"{self.student.username}-Score:{self.score}”
- Добавьте вновь созданное приложение в список
INSTALLED_APPS
в файлеsettings.py
. - Выполните команды
python manage.py makemigrations
иpython manage.py migrate
для создания таблицы для записи оценки студента. - Зарегистрируйте модель в админке Django, добавив в файл
admin.py
следующее:
from django.contrib import admin
from .models import StudentAssessmentRecord
@admin.register(StudentAssessmentRecord)
class StudentAssessmentRecordAdmin(admin.ModelAdmin):
list_display = ["id", "student", "score"]
- Войдите на сайт администратора, чтобы увидеть таблицы.
Создание ролей
Как уже говорилось, для представления ролей мы будем использовать модель Group
. Итак, давайте создадим группу Teacher из панели администратора.
Разрешения по умолчанию
В предыдущем разделе мы создали группу Teacher и назначили ей определенные права через администратора сайта Django. Если вам было интересно узнать о происхождении этих прав, то этот раздел внесет ясность, которую вы искали.
Для каждой созданной модели Django обычно создает четыре разрешения по умолчанию, а именно:
- Can view - предоставление пользователям доступа к чтению экземпляров модели.
- Can change - предоставление пользователям доступа к обновлению экземпляров модели.
- Can add - предоставление пользователям доступа к созданию экземпляров модели.
- Can delete - предоставление пользователям доступа к удалению экземпляров модели.
В результате вышеизложенного при создании модели записи оценки студента были созданы эти четыре разрешения по умолчанию. Именно поэтому они доступны в списке разрешений при создании группы Teacher.
Программное управление пользователями, группами и разрешениями
Для создания группы учителей мы использовали панель администратора Django. Мы также можем создать и сделать то же самое с помощью программы. Давайте сделаем это следующим образом:
- Выполните команду
python manage.py shell
Да, мы только что создали группу студентов. Мы импортировали модель Group
из приложения аутентификации и создали группу Student с именем "Student".
Как добавить Разрешения в группу студентов?
Мы воспользуемся связанным менеджером .permissions - student_group.permissions
.
Прежде чем приступить к добавлению разрешений, давайте подробнее познакомимся с объектом Permission.
Объекты Permission имеют следующие поля:
- Name (Имя) (Обязательно): 255 символов или меньше.
- Content_type (Тип контента) (Обязательно): Ссылка на таблицу базы данных django_content_type, которая содержит запись для каждой установленной модели.
- Codename (Кодовое имя) (Обязательно): 100 символов или меньше.
Помните, что по умолчанию для каждой модели создается четыре разрешения. Давайте познакомимся с принятым в Django соглашением об именовании разрешений.
Имена разрешений имеют вид <APP_NAME>.<PERMISSION_CODENAME>
.
В нашем случае разрешение на просмотр всех экземпляров записи об оценке студента в приложении record будет выглядеть так: record.view_studentassessmentrecord
.
Давайте назначим группе студентов одно из этих стандартных разрешений. student_group.permissions.add(permission)
. Помните, что нам нужно будет передать ID объекта разрешения или сам объект разрешения.
Совет: Обращайтесь с ней так же, как и с любой другой моделью Django, никакой разницы нет.
Давайте вернемся в оболочку или снова выполним в терминале команду python manage.py shell
, чтобы выполнить следующие действия:
- Импортируйте модель разрешений и модель типа содержимого
- Получите тип содержимого для модели записи оценки студента
- Получите объект разрешения
- Добавьте объект разрешения в поле типа "многие-ко-многим" -
permissions of student_group
Для роли Principal (Директор) создадим группу Principal и назначим ей разрешения на создание, изменение, просмотр и удаление:
- Пользователь
- Запись оценок студентов
Давайте сделаем это в программе.
- Получите тип содержимого для моделей
User
иStudentAssessmentRecord
. - Получите все объекты разрешений для типа содержимого "Пользователь" и типа содержимого "Запись оценки студента".
- Создайте группу Principal (Директор).
- Объедините все объекты разрешений для записей об оценках пользователей и студентов в один набор запросов с помощью оператора OR (символ трубы).
- Назначьте комбинированные разрешения группе Principal, установив разрешения для группы Principal.
Проверка контроля доступа и применение разрешений
До сих пор мы говорили о пользователях, ролях и разрешениях. Теперь давайте поговорим о том, как использовать эти разрешения. Ведь простое наличие ролей и прав доступа не означает автоматического ограничения каких-либо действий в нашем приложении. Чтобы реализовать эффективный контроль доступа, необходимо использовать эти разрешения на практике, выполняя проверки контроля доступа.
Проверки контроля доступа позволяют использовать созданные разрешения для предоставления (или запрета) доступа пользователей к различным частям приложения. Другими словами, пользователь получает доступ к привилегированной части приложения, если у него (или у группы, в которую он входит) есть разрешение на доступ к этой части.
Для проверки наличия прав доступа мы можем использовать метод user.has_perm()
.
В шаблоне доступ к правам, связанным с аутентифицированным пользователем, можно получить в переменной шаблона {{ perms }}
.
Для получения более подробной информации о системе прав доступа и аутентификации Django обратитесь к документации Django, в которой содержится исчерпывающая информация и подробные примеры. Счастливого изучения!
Заключение
В заключение мы рассмотрели реализацию ролевого управления доступом (RBAC) с использованием встроенных возможностей Django, обеспечив надежный фундамент для управления доступом в ваших приложениях.
Продолжая совершенствовать безопасность и масштабируемость приложения, вы обнаружите, что управление гранулярными разрешениями в масштабе становится все более сложной задачей. В этом случае стоит обратить внимание на Permify. Это служба авторизации с открытым исходным кодом на базе Google Zanzibar, которая позволяет легко создавать тонкие разрешения в масштабе.
С Permify вы получите мощный инструмент, позволяющий без особых усилий поднять уровень управления доступом.