Как создать пользователя только для чтения в PostgreSQL?

302

Я хотел бы создать пользователя в 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.

Теги:

9 ответов

428
Лучший ответ

Использование гранта/выбор одной таблицы

Если вы предоставляете CONNECT только базе данных, пользователь может подключиться, но не имеет других привилегий. Вы должны предоставить ИСПОЛЬЗОВАНИЕ на пространствах имен (схемы) и 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 вы можете предоставлять разрешения для всех таблиц/представлений/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 для GRANT SELECT для всех таблиц, представлений и последовательностей для публики, для любви к copy-n-paste. Естественно, это будет применяться только к уже созданным таблицам.

  • 21
    Вы должны поместить свои изменения относительно PG9 вверху поста.
  • 0
    Я отправил изменения на основе вашего запроса, Данило.
Показать ещё 6 комментариев
30

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

test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;
GRANT
  • 1
    Я должен был быть в конкретной базе данных, чтобы это работало. Postgresql 9.5.
  • 7
    Это работает только для существующих таблиц в схеме. Если пользователь write позже создает или заменяет таблицы, пользователь только для чтения не будет иметь к ним доступа
17

Вот лучший способ найти пользователей только для чтения (используя 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
  • 2
    Мне нравится подход, но мне также нужно было предоставить GRANT CONNECT ON DATABASE [thedatabase] TO [theuser или role]; и ПРЕДОСТАВЛЯТЬ ИСПОЛЬЗОВАНИЕ В СХЕМЕ общественности [пользователь или роль];
  • 1
    Общедоступная схема все еще позволяет такому пользователю создавать таблицы. Кроме того, новые таблицы не рассматриваются, как и последовательности. К сожалению, все это немного сложнее, чем это. : - / Я опубликую то, что я закончил делать, как только я подтвердил это еще немного.
Показать ещё 2 комментария
7

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

6

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

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

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

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

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;
  • 1
    Это очень хороший ответ, за исключением одного: ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User; что также позволило бы читать все таблицы, созданные в одной и той же БД в будущем.
  • 0
    Необычно разрешать пользователю доступ только для чтения к последовательностям. Чтение последовательности обновляет ее, и они обычно нужны только для INSERT .
2

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

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

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

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

0

Взято из ссылки, размещенной в ответ на despesz '.

Postgres 9.x, как представляется, имеет возможность делать то, что запрашивается. См. Пункт "Предоставление по объектам базы данных":

http://www.postgresql.org/docs/current/interactive/sql-grant.html

Где он говорит: "Существует также возможность предоставлять привилегии для всех объектов одного и того же типа в одной или нескольких схемах. Эта функциональность в настоящее время поддерживается только для таблиц, последовательностей и функций (но обратите внимание, что ВСЕ ТАБЛИЦЫ для включения представлений и внешних таблиц).

На этой странице также обсуждается использование ROLE и PRIVILEGE под названием "ВСЕ ПРИВИЛЕГИИ".

Также присутствует информация о том, как функциональность GRANT сравнивается со стандартами SQL.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню