PostgreSQL: отказано в разрешении для связи


14

Я немного запутался в настройке разрешений в PostgreSQL.

У меня есть эти роли:

                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 admin     | Superuser, Create role, Create DB, Replication | {}
 meltemi   | Create role, Create DB                         | {rails}
 rails     | Create DB, Cannot login                        | {}
 myapp     |                                                | {rails}

и базы данных:

                                    List of databases
        Name         | Owner  | Encoding |   Collate   |    Ctype    | Access privileges 
---------------------+--------+----------+-------------+-------------+-------------------
 myapp_production    | rails  | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 ...

У пользователя myappнет проблем с запросом к myapp_productionбазе данных, добавлением и удалением записей. Я хотел бы meltemiтакже иметь возможность запрашивать ту же базу данных. Итак, я создал роль, railsкоторая владеет базой данных и сделал meltemiи myappчленов и членов rails. Но я все еще получаю permission denied for relationошибки. Meltemiможет просматривать схему, но не может запрашивать БД.

Я только что заметил (с помощью \dtкоманды), что myappявляется владельцем таблиц:

             List of relations
 Schema |       Name        | Type  | Owner 
--------+-------------------+-------+-------
 public | events            | table | myapp
 public | schema_migrations | table | myapp
 ...
 public | users             | table | myapp
 ...

Таблицы были созданы с помощью ORM (миграции ActiveRecord от Rails).

Я знаю, что авторизация в PostgreSQL сильно отличается (в отличие от MySQL и других, которые я использовал). Как мне настроить свою базу данных, чтобы разные пользователи могли получить к ней доступ? Некоторые должны быть в состоянии CRUD, но другие могут только читать, и т.д ...

Спасибо за любую помощь. Извините, я знаю, что это очень простой вопрос, но я не смог найти ответ сам.

Ответы:


4

Я только что написал об этом в своем ответе на Предоставление прав на базу данных postgresql другому пользователю на ServerFault.

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

Таким образом, в вашем случае railsпереименовывается, чтобы сказать myapp_users, а затем вы создаете новую роль входа (пользователь) с именем railsи GRANT myapp_users TO rails. Теперь вы GRANT myapp_users TO meltemi. И новая railsучетная запись, и meltemiпользователь теперь имеют права старой railsучетной записи.

Для более детального контроля я обычно советую вам избегать ежедневного входа пользователей или их групп в владение таблицами. Предоставьте им доступ через NOINHERITгруппу, которую они должны явно SET GROUPили, что лучше, использовать совершенно другому пользователю для привилегированных операций, таких как DDL и GRANTs. К сожалению, это не работает с Rails, потому что Rails любит применять миграцию всякий раз, когда ему это нравится, и AFAIK не дает вам возможности указать другого, более привилегированного пользователя для запуска миграций.


ОК, прочитайте пост, на который вы ссылались; очень полезно! Теперь, если я правильно понимаю вещи, я думаю, что вы могли использовать myappвместо railsвыше? Потому что myappвладеет таблицами (я никогда не указывал, что миграция должна иметь). Во всяком случае, было бы Сорта иметь смысл , если я переименовал myappв , myapp_groupа затем сделал новый пользователь , myappкоторый рельсы приложения будет использовать для подключения к БД. Сделайте myappи существующие meltemi, оба участники myapp_groupроли. Но что происходит, когда я запускаю следующую миграцию. не будет ли оно принадлежать myappвоссозданию проблемы заново?!?
Meltemi

1
Вы должны понимать, что PostgreSQL имеет только roles(начиная с версии 8.1). Условия userи groupхранятся по историческим причинам и совместимости. По сути, «группа» - это роль без права входа в систему. Вы можете предоставить , myappчтобы meltemiдаже если myappэто просто еще один «пользователь». Начните с чтения руководства здесь .
Эрвин Брандштеттер

Я понимаю rolesпротив groupsпротив usersразделения в Postgres, по крайней мере , я думаю , что я делаю. Извините, что использовал неправильную (и запутанную) терминологию выше. Но я до сих пор не понимаю, как настроить свою базу данных, чтобы роль без входа в систему СВОИЛА базу данных и две роли входа в систему, myappи meltemiобе могли иметь полный доступ. Одной из этих ролей myappбудет запуск миграций Rails , которые неизбежно будут создавать новые таблицы, которые снова будут принадлежать пользователю myappвхода в систему. Должен ли я просто стать meltemi«членом» myappи покончить с этим? Но это только кажется глупым ... нет?!?
Мелтеми

1
@Meltemi: Если вы хотите предоставить все привилегии, которые у вас myappесть meltemi, то это было бы правильно. Если вы хотите meltemiполучить только часть привилегий, это не так. Затем создайте групповую роль для хранения набора привилегий и предоставьте его meltemi. Скорее всего, вас заинтересует этот связанный вопрос о SO . Я ответил объясняяDEFAULT PRIVILEGES
Эрвин Брандштеттер

@Meltemi Да, как обычно миграция Rails усложняет картину. Rails действительно должен позволить вам указать другую учетную запись пользователя для запуска миграций. Возможно, вы можете добавить SET ROLEкоманду в начало ваших миграций и RESET ROLEдо конца, но я бы не стал доверять Rails, чтобы все выполнялось аккуратно по порядку. Эрвин прав; в этом случае лучший обходной путь будет для GRANTпользователя: rails передает права собственности другому пользователю, используя 1-го пользователя в качестве группы для второго.
Крейг Рингер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.