22.3. Членство в роли #
Часто бывает удобно сгруппировать пользователей для упрощения управления правами: права можно выдавать для всей группы и у всей группы забирать. В PostgreSQL для этого создаётся роль, представляющая группу, а затем членство в этой группе выдаётся ролям индивидуальных пользователей.
Для настройки групповой роли сначала нужно создать саму роль:
CREATE ROLE имя
;
Обычно групповая роль не имеет атрибута LOGIN
, хотя при желании его можно установить.
После того как групповая роль создана, в неё можно добавлять или удалять членов, используя команды GRANT
и REVOKE
:
GRANTгрупповая_роль
TOроль1
, ... ; REVOKEгрупповая_роль
FROMроль1
, ... ;
Членом роли может быть и другая групповая роль (потому что в действительности нет никаких различий между групповыми и не групповыми ролями). При этом база данных не допускает замыкания членства по кругу. Также не допускается управление членством роли PUBLIC
в других ролях.
Члены групповой роли могут использовать её права двумя способами. Во-первых, члены группы, которым было предоставлено членство с атрибутом SET
, могут выполнить команду SET ROLE
, чтобы временно «стать» групповой ролью. В этом состоянии сеанс базы данных имеет доступ к правам групповой роли вместо исходной роли, от имени которой был выполнен вход в систему. При этом для всех создаваемых объектов базы данных владельцем считается групповая, а не исходная роль. Во-вторых, члены группы, которым было предоставлено членство с атрибутом INHERIT
, автоматически используют права ролей, членами которых они являются прямо или косвенно, вплоть до роли без атрибута INHERIT
. Например:
CREATE ROLE joe LOGIN; CREATE ROLE admin; CREATE ROLE wheel; CREATE ROLE island; GRANT admin TO joe WITH INHERIT TRUE; GRANT wheel TO admin WITH INHERIT FALSE; GRANT island TO joe WITH INHERIT TRUE, SET FALSE;
После подключения с ролью joe
сеанс базы данных будет использовать права, выданные напрямую joe
, и права, выданные ролям admin
и island
, так как joe
«наследует» эти права. Однако права, выданные wheel
, будут недоступны, потому что, хотя joe
косвенно является членом wheel
, это членство получено через роль admin
, которая была выдана с атрибутом WITH INHERIT FALSE
. После выполнения команды:
SET ROLE admin;
сеанс будет использовать только права, выданные admin
, а не права, выданные роли joe
или island
. После выполнения команды:
SET ROLE wheel;
сеанс будет использовать только права, выданные wheel
, а не права, выданные joe
или admin
. Начальный набор прав можно восстановить любой из команд:
SET ROLE joe; SET ROLE NONE; RESET ROLE;
Примечание
Команда SET ROLE
в любой момент разрешает выбрать любую роль, прямым или косвенным членом которой является оригинальная роль, под которой был выполнен вход в систему, при условии, что существует цепочка членства в ролях, каждая из которых имеет атрибут SET TRUE
(установленный по умолчанию). Поэтому в примере выше не обязательно сначала становиться admin
перед тем как стать wheel
. С другой стороны, стать island
не получится вовсе, а joe
может получить доступ к правам только через механизм наследования.
Примечание
В стандарте SQL есть чёткое различие между пользователями и ролями. При этом пользователи, в отличие от ролей, не наследуют права автоматически. Такое поведение может быть получено в PostgreSQL, если для ролей, используемых как роли в стандарте SQL, устанавливать атрибут INHERIT
, а для ролей-пользователей в стандарте SQL — атрибут NOINHERIT
. Однако в PostgreSQL все роли по умолчанию имеют атрибут INHERIT
. Это сделано для обратной совместимости с версиями до 8.1, в которых пользователи всегда могли использовать права групп, членами которых они являются.
Атрибуты роли LOGIN
, SUPERUSER
, CREATEDB
и CREATEROLE
можно рассматривать как особые права, но они никогда не наследуются как обычные права на объекты базы данных. Чтобы ими воспользоваться, необходимо переключиться на роль, имеющую этот атрибут, с помощью команды SET ROLE
. Продолжая предыдущий пример, можно установить атрибуты CREATEDB
и CREATEROLE
для роли admin
. Затем при входе с ролью joe
, получить доступ к этим правам будет возможно только после выполнения SET ROLE admin
.
Для удаления групповой роли используется DROP ROLE
:
DROP ROLE имя
;
Любое членство в групповой роли будет автоматически отозвано (в остальном на членов этой роли это никак не повлияет).