Как создать пользователя только для чтения в PostgreSQL? - PullRequest
368 голосов
/ 17 апреля 2009

Я бы хотел создать пользователя в PostgreSQL, который может делать SELECT только из конкретной базы данных. В 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.

Ответы [ 11 ]

568 голосов
/ 18 апреля 2009

Предоставить использование / выбрать одну таблицу

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

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 вы можете предоставлять разрешения для всех таблиц / представлений / и т. Д. В схеме, используя одну команду, вместо того, чтобы вводить их по одному:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;

Это влияет только на таблицы, которые уже были созданы. Более эффективно, вы можете автоматически назначить роли по умолчанию для новых объектов в будущем:

ALTER DEFAULT PRIVILEGES IN SCHEMA public
   GRANT SELECT ON TABLES TO xxx;

Обратите внимание, что по умолчанию это повлияет только на объекты (таблицы), созданные пользователем, который выполнил эту команду: хотя она также может быть установлена ​​для любой роли, членом которой является выдавший пользователь. Однако вы не выбираете привилегии по умолчанию для всех ролей, в которых вы участвуете, при создании новых объектов ... так что все еще есть некоторые недоработки. Если вы принимаете подход, согласно которому база данных играет роль-владелец, а изменения схемы выполняются в качестве этой роли-владельца, вам следует назначить привилегии по умолчанию для этой роли-владельца. ИМХО, это немного сбивает с толку, и вам, возможно, придется поэкспериментировать, чтобы придумать функциональный рабочий процесс.

Несколько таблиц / представлений (версии 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 в GRANT SELECT для всех открытых таблиц, представлений и последовательностей для копирования-n-paste. Естественно, это будет применяться только к таблицам, которые уже были созданы.

35 голосов
/ 20 июня 2010

Обратите внимание, что PostgreSQL 9.0 (сегодня в бета-тестировании) будет иметь простой способ сделать это :

test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;
GRANT
21 голосов
/ 06 сентября 2013

Вот лучший способ добавления пользователей, доступных только для чтения (с использованием 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
18 голосов
/ 04 февраля 2017

Ссылка взята из этого блога:

Скрипт для создания пользователя только для чтения:

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;
11 голосов
/ 19 августа 2016

По умолчанию новые пользователи будут иметь разрешение на создание таблиц. Если вы планируете создать пользователя только для чтения, это, вероятно, не то, что вам нужно.

Чтобы создать истинного пользователя только для чтения с 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;
8 голосов
/ 15 августа 2014

Я создал удобный скрипт для этого; pg_grant_read_to_db.sh . Этот сценарий предоставляет привилегии только для чтения указанной роли для всех таблиц, представлений и последовательностей в схеме базы данных и устанавливает их по умолчанию.

2 голосов
/ 28 марта 2017

Если ваша база данных находится в общедоступной схеме, это легко (предполагается, что вы уже создали 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
1 голос
/ 15 января 2019

Я прочитал все возможные решения, и все в порядке, если вы помните, чтобы подключиться к базе данных, прежде чем предоставить вещи;) В любом случае спасибо всем остальным решениям !!!

user@server:~$ sudo su - postgres

создать пользователя psql:

postgres@server:~$ createuser --interactive 
Enter name of role to add: readonly
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

запустите psql cli и установите пароль для созданного пользователя:

postgres@server:~$ psql
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
Type "help" for help.

postgres=# alter user readonly with password 'readonly';
ALTER ROLE

подключиться к целевой базе данных:

postgres=# \c target_database 
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
You are now connected to database "target_database" as user "postgres".

предоставьте все необходимые привилегии:

target_database=# GRANT CONNECT ON DATABASE target_database TO readonly;
GRANT

target_database=# GRANT USAGE ON SCHEMA public TO readonly ;
GRANT

target_database=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly ;
GRANT

изменить привилегии по умолчанию для целей db public shema:

target_database=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES
1 голос
/ 17 апреля 2009

Непростой способ сделать это - выбрать select для каждой таблицы базы данных:

postgres=# grant select on db_name.table_name to read_only_user;

Вы можете автоматизировать это, генерируя ваши заявления о предоставлении гранта из метаданных базы данных.

0 голосов
/ 14 мая 2019
CREATE USER username SUPERUSER  password 'userpass';
ALTER USER username set default_transaction_read_only = on;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...