Як створити користувача, доступного лише для читання в PostgreSQL?


419

Я хотів би створити користувача в 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.

Відповіді:


641

Дозволити використання / вибрати для однієї таблиці

Якщо ви надаєте 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;

Зауважте, що за замовчуванням це вплине лише на об'єкти (таблиці), створені користувачем, який видав цю команду: хоча він також може бути встановлений для будь-якої ролі, членом якого видається користувач. Однак ви не отримуєте привілеїв за замовчуванням для всіх ролей, до яких ви входите, створюючи нові об'єкти ... тож все ще є деякі фальсифікації. Якщо ви прийняли підхід про те, що база даних має роль власника, а зміни схеми виконуються як ті, що є власником, то вам слід призначити привілеї за замовчуванням для цієї ролі володіння. 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 на всіх таблицях, переглядах та послідовностях у відкритому доступі для копіювання та вставки любові. Природно, це стосуватиметься лише таблиць, які вже створені.


22
Ви повинні розмістити свої зміни щодо PG9 вгорі публікації.
Данило Барген

5
Приємно. Я хочу додати ще одне, що вам може знадобитися дозволити читати послідовності цим користувачем; так: ВИБІРТЕ ВИБІР ВСІХ ПОСЛІДКІВ У СХЕМУ public to TO xxx;
JJC

26
Зауважте, що для того, щоб цей користувач не міг створювати нові таблиці, мені довелося REVOKE CREATE ON SCHEMA public FROM PUBLIC;. Без цього користувач "лише для читання" не міг змінювати існуючі таблиці, але міг створювати нові таблиці в схемі та додавати / видаляти дані з цих таблиць.
Ajedi32

3
@ Ajedi32 Це має бути частиною прийнятої відповіді! Спасибі
Асфанд Казі

12
Для новачків, таких як я, я думаю, варто згадати, що слід запускати консоль, використовуючи psql mydbінакше більшість цих маніпуляцій не буде робити. Особисто мені знадобилося чимало часу, щоб розібратися в цьому моїм власним. Сподіваюся, що це комусь допоможе.
Анас

41

Зауважте, що PostgreSQL 9.0 (сьогодні в бета-тестуванні) матиме простий спосіб зробити це :

test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;

3
Я мав бути в конкретній базі даних, щоб це працювало. Postgresql 9.5.
користувач1158559

8
Це працює лише для існуючих таблиць у схемі. Якщо пізніше користувач запису створить або замінить таблиці, користувач, який
читає тільки,

32

Довідка з цього блогу:

Сценарій для створення користувача лише для читання:

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;

6
Це дуже хороша відповідь, за винятком однієї речі, ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User; яка також дозволила б читати всі таблиці, створені в одній БД у майбутньому.
Равбакер

2
Незвично дозволяти користувачеві доступ лише до читання. Читання послідовності оновлює її, і вони, як правило, потрібні лише для INSERTs.
jpmc26

Для повноти, можливо, додайте:GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA schema_name TO Read_Only_User;
Хаддаді

@ jpmc26: це означає, що ти рекомендуєш GRANT ALL ON ALL SEQUENCES IN SCHEMA schema_name TO Read_Only_User:?
Фаб’єн Хаддаді

@FabienHaddadi Це означає, що, якщо у вас є якісь звичайні вимоги, я не бачу необхідності надавати будь-які дозволи для послідовностей користувачеві, який читає лише.
jpmc26

24

Ось найкращий спосіб додати користувачів лише для читання (використовуючи 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;

Потім увійдіть у всі пов’язані машини (головний + ведучий читання-вежі / гарячі очікування тощо) та запустіть:

$ 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
Мені подобається підхід, але мені також потрібно було ЗВ'ЯЗКУВАТИ ЗВ'ЯЗКУ ДАНИХ [базу даних] ДО [користувач або роль]; та ВИКОРИСТАННЯ ВИКОРИСТАННЯ НА СХЕМІ громадськості [користувач або роль];
Ян Коннор

1
Загальнодоступна схема все ще дозволяє такому користувачеві створювати таблиці. Також нові таблиці не висвітлюються, а також послідовності. На жаль, це все трохи складніше, ніж це. : - / Я опублікую те, що в кінцевому підсумку робив, коли ще раз це підтвердив.
JJC

У вищезгаданому сценарії ви намагаєтесь створити роль двічі. Я підозрюю, що ви мали намір використовувати "ALTER ROLE ..." під час увімкнення ролі для входу та встановлення пароля
Богдан

Якщо у вас вже є користувач, після створення ролі для повторного використання та надання дозволу select perms надайте користувачеві нову роль:
ВИГОТОВЛЯЙТЕ читати тільки

18

За замовчуванням нові користувачі матимуть дозвіл на створення таблиць. Якщо ви плануєте створити користувача лише для читання, це, мабуть, не те, що ви хочете.

Щоб створити справжнього користувача лише для читання за допомогою 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

Я створив для цього зручний сценарій; pg_grant_read_to_db.sh . Цей скрипт надає права доступу лише для читання визначеній ролі для всіх таблиць, подань та послідовностей у схемі бази даних та встановлює їх за замовчуванням.


4

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

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

3

Якщо ваша база даних знаходиться у загальнодоступній схемі, це легко (це передбачає, що ви вже створили 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.