Как создать пользователя только для чтения в PostgreSQL?
Я хотел бы создать пользователя в PostgreSQL, который может делать только выбор из конкретной базы данных. В MySQL команда была бы:
GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy';
что такое эквивалентная команда или серия команд в PostgreSQL?
я попробовал...
postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;
но похоже, что единственными вещами, которые вы можете предоставить в базе данных, являются CREATE, CONNECT, TEMPORARY и TEMP.
9 ответов:
предоставить использование / выбрать в одну таблицу
если вы предоставляете только подключение к базе данных, пользователь может подключиться, но не имеет других привилегий. Вы должны предоставить использование в пространствах имен (схемах) и выбрать в таблицах и представлениях по отдельности следующим образом:
GRANT CONNECT ON DATABASE mydb TO xxx; -- This assumes you're actually connected to mydb.. GRANT USAGE ON SCHEMA public TO xxx; GRANT SELECT ON mytable TO xxx;несколько таблиц / представлений (PostgreSQL 9.0+)
в последних версиях PostgreSQL вы можете предоставить разрешения на все таблицы / представления / etc в схеме с помощью одной команды, а не вводить их один за другим:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;это влияет только на таблицы, которые уже были созданы. Более мощно, вы можете автоматически иметь роли по умолчанию, назначенные новым объектам в перспективе:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO xxx;обратите внимание, что по умолчанию это будет влиять только на объекты (таблицы), созданные пользователем, который выдал эту команду: хотя он также может быть установлен на любой роли, членом которой является пользователь-эмитент. Однако вы не получаете привилегии по умолчанию для всех ролей, членом которых вы являетесь при создании новых объектов... так что тут еще кое-что есть. Если вы применяете подход, согласно которому база данных имеет роль-владельца, и изменения схемы выполняются как эта роль-владелец, то вы должны назначить привилегии по умолчанию этой роли-владельцу. IMHO это все немного запутанно, и вам может понадобиться поэкспериментировать, чтобы придумать функциональный рабочий процесс.
несколько таблиц/представлений (версии PostgreSQL до 9.0)
чтобы избежать ошибок в длительных, многостоловых изменениях, это рекомендуется использовать следующий "автоматический" процесс для создания необходимого
GRANT SELECTдля каждой таблицы/вид:SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;' FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S');это должно вывести соответствующие команды гранта, чтобы предоставить SELECT на всех таблицах, представлениях и последовательностях публично, для copy-n-paste love. Естественно, это будет применяться только к таблицам, которые уже были созданы.
обратите внимание, что PostgreSQL 9.0 (сегодня в бета-тестировании) будет иметь простой способ сделать это:
test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser; GRANT
вот лучший способ, который я нашел, чтобы добавить пользователей только для чтения (с помощью PostgreSQL 9.0 или новее):
$ sudo -upostgres psql postgres postgres=# CREATE ROLE readonly WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE'; postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;затем войдите на все связанные машины(master + read-slave(s)/hot-standby (s) и т. д..) и бегом:
$ echo "hostssl <PUT_DBNAME_HERE> <PUT_READONLY_USERNAME_HERE> 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/9.2/main/pg_hba.conf $ sudo service postgresql reload
скрипт для создания пользователя только для чтения:
CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';назначьте разрешение этому пользователю только для чтения:
GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User; GRANT USAGE ON SCHEMA public TO Read_Only_User; GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User; GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;
по умолчанию новые пользователи будут иметь разрешение на создание таблиц. Если вы планируете создать только для чтения, это не то, что вы хотите.
создать истинно только для чтения с PostgreSQL 9.0+, выполните следующие действия:
# This will prevent default users from creating tables REVOKE CREATE ON SCHEMA public FROM public; # If you want to grant a write user permission to create tables # note that superusers will always be able to create tables anyway GRANT CREATE ON SCHEMA public to writeuser; # Now create the read-only user CREATE ROLE readonlyuser WITH LOGIN ENCRYPTED PASSWORD 'strongpassword'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser;если ваш пользователь только для чтения не имеет разрешения на список таблиц (т. е.
\dне возвращает никаких результатов), это, вероятно, потому, что у вас нетUSAGEразрешения для схемы.USAGE- это разрешение, которое позволяет пользователям фактически используйте разрешения, которые они были назначены. Какой в этом смысл? Я не уверен. Чтобы исправить:# You can either grant USAGE to everyone GRANT USAGE ON SCHEMA public TO public; # Or grant it just to your read only user GRANT USAGE ON SCHEMA public TO readonlyuser;
Я создал удобный скрипт для этого;pg_grant_read_to_db.sh. этот сценарий предоставляет привилегии только для чтения указанной роли для всех таблиц, представлений и последовательностей в схеме базы данных и устанавливает их по умолчанию.
если ваша база данных находится в открытом схемы, это легко (это предполагает, что вы уже создали
readonlyuser)db=> GRANT SELECT ON ALL TABLES IN SCHEMA public to readonlyuser; GRANT db=> GRANT CONNECT ON DATABASE mydatabase to readonlyuser; GRANT db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public to readonlyuser; GRANTесли ваша база данных использует
customschema, выполните описанное выше, но добавьте еще одну команду:db=> ALTER USER readonlyuser SET search_path=customschema, public; ALTER ROLE
не простой способ сделать это будет предоставление select на каждой таблице базы данных:
postgres=# grant select on db_name.table_name to read_only_user;вы можете автоматизировать это, создав инструкции grant из метаданных базы данных.
взято из ссылки, опубликованной в ответ на despesz' ссылка.
Postgres 9.x, похоже, имеет возможность делать то, что требуется. См. пункт грант на объекты базы данных:
http://www.postgresql.org/docs/current/interactive/sql-grant.html
где говорится: "существует также возможность предоставления привилегий на все объекты одного типа в одной или нескольких схемах. В настоящее время эта функция поддерживается только для таблиц, последовательностей и функций (но обратите внимание, что все таблицы считаются включающими представления и внешние таблицы)."
на этой странице также обсуждается использование ролей и привилегий, называемых "все привилегии".
также присутствует информация о том, как функции гранта сравниваются со стандартами SQL.
Comments