Как создать пользователя только для чтения в 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 usage / выберите для одной таблицы

если вы предоставляете только подключение к базе данных, пользователь может подключиться, но не имеет других привилегий. Вы должны предоставить использование в пространствах имен (схемах) и выбрать в таблицах и представлениях индивидуально:

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');

это должно вывести соответствующие команды GRANT для предоставления 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.