Я думаю, ви суперечите автентифікацію та авторизацію .
Я повністю погоджуюся, що зберігати модель безпеки в БД є розумним, тим більше, що LedgerSMB розроблений з урахуванням доступу кількох клієнтів. Якщо ви не плануєте на 3-й рівня з проміжним шаром має ідеальний сенс мати користувач в якості ролей бази даних, особливо для що - щось на зразок обліку додатки.
Це не означає, що вам доведеться аутентифікувати користувачів проти бази даних, використовуючи підтримуваний PostgreSQL метод аутентифікації. Користувачі вашої бази даних, ролі та гранти можуть використовуватися для авторизації лише за вашим бажанням.
Ось як працює для веб-інтерфейсу, наприклад:
jane
підключається до веб-сервера ui та автентифікується, використовуючи будь-який бажаний метод, скажімо, рукостискання з клієнтським сертифікатом HTTPS X.509 та DIGEST auth. Тепер сервер має підключення від користувача, який він приймає насправді jane
.
Сервер підключається до PostgreSQL за допомогою фіксованого імені користувача / пароля (або Kerberos або будь-якого іншого), автентифікуючи себе на сервері db як користувачеві webui
. Сервер db довіряє webui
аутентифікувати своїх користувачів, тому webui
було надано відповідні GRANT
s (див. Нижче).
Під час цього з'єднання сервер використовує, SET ROLE jane;
щоб припустити рівень авторизації користувача jane
. Поки RESET ROLE;
або SET ROLE
не запущено інше , з'єднання функціонує з тими ж правами доступу, що jane
і з SELECT current_user()
ін jane
.
Сервер підтримує зв'язок між підключенням до бази даних, на якому він має SET ROLE
перейти, jane
та веб-сеансом для користувача jane
, не дозволяючи, щоб PostgreSQL-з'єднання використовувалося іншими з'єднаннями з іншими користувачами без нового SET ROLE
проміжку.
Тепер ви автентифікуєтесь поза сервером, але зберігаєте авторизацію на сервері. Pg повинен знати, які існують користувачі, але не потребує паролів або методів аутентифікації для них.
Побачити:
Деталі
Сервер webui контролює виконання запитів, і він не збирається дозволяти jane
запускати необроблений SQL (сподіваюся!), Тому jane
не може RESET ROLE; SET ROLE special_admin_user;
через веб-інтерфейс. Для додаткової безпеки я додав би фільтр операторів на сервер, який відхилив, SET ROLE
і RESET ROLE
якщо тільки з'єднання не було або входило в пул непризначених з'єднань.
Ви все ще можете використовувати пряму автентифікацію на Pg в інших клієнтах; можна вільно змішувати та поєднувати Ви просто повинні GRANT
на webui
користувача права SET ROLE
користувачів , які можуть увійти в систему через Інтернет , а потім дати цим користувачам будь-які звичайні CONNECT
права, паролі і т.д. , які ви хочете. Якщо ви хочете зробити їх лише в Інтернеті, REVOKE
їх CONNECT
права на базу даних (і з public
).
Щоб зробити такий розрив автентифікації / авторизації, я маю особливу роль, assume_any_user
яку я повинен виконувати GRANT
кожному новоствореному користувачеві. Потім я перейду GRANT assume_any_user
до справжнього імені користувача, використовуваного такими речами, як довірена веб-сторінка, надаючи їм права стати будь-яким користувачем, який їм подобається.
Дуже важливо , щоб assume_any_user
на NOINHERIT
роль, так що webui
користувач або будь-який інший не має privilges від своєї самості і може діяти тільки в базі даних , як тільки це SET ROLE
для реального користувача. Ні за яких обставин не повинно webui
бути власником або власником БД .
Якщо ви з'єднуєте з'єднання, ви можете використовувати SET LOCAL ROLE
для встановлення ролі лише в рамках транзакції, щоб ви могли повернути з'єднання до пулу після COMMIT
або ROLLBACK
. Остерігайтеся, що це RESET ROLE
все ще працює, тому досі клієнт не може дозволити запускати будь-який SQL, який він хоче.
SET SESSION AUTHORIZATION
- пов'язана, але сильніша версія цієї команди. Це не вимагає членства в ролі, але це лише команда суперпользователя. Ви не хочете, щоб ваш веб-інтерфейс підключався як супер-користувач. Це може бути скасовано з RESET SESSION AUTHORIZATION
, SET SESSION AUTHORIZATION DEFAULT
або SET SESSION AUTHORIZATION theusername
повернути права суперкористувача , так що це не привілей , скидаючи бар'єр безпеки або.
Команда, яка працювала на кшталт, SET SESSION AUTHORIZATION
але була незворотною і діяла б, якби ви були членом ролі, але не суперпользователем, було б чудово. Наразі цього немає, але ви все одно можете добре розділити аутентифікацію та авторизацію, якщо ви обережні.
Приклад та пояснення
CREATE ROLE dbowner NOLOGIN;
CREATE TABLE test_table(x text);
INSERT INTO test_table(x) VALUES ('bork');
ALTER TABLE test_table OWNER TO dbowner;
CREATE ROLE assume_any_user NOINHERIT NOLOGIN;
CREATE ROLE webui LOGIN PASSWORD 'somepw' IN ROLE assume_any_user;
CREATE ROLE jane LOGIN PASSWORD 'somepw';
GRANT jane TO assume_any_user;
GRANT ALL ON TABLE test_table TO jane;
CREATE ROLE jim LOGIN PASSWORD 'somepw';
GRANT jim TO assume_any_user;
Тепер підключіть як webui
. Зверніть увагу , що ви не можете нічого зробити , test_table
але ви можете SET ROLE
з jane
і потім ви можете отримати доступ до test_table
:
$ psql -h 127.0.0.1 -U webui regress
Password for user webui:
regress=> SELECT session_user, current_user;
session_user | current_user
--------------+--------------
webui | webui
(1 row)
regress=> SELECT * FROM test_table;
ERROR: permission denied for relation test_table
regress=> SET ROLE jane;
SET
regress=> SELECT session_user, current_user;
session_user | current_user
--------------+--------------
webui | jane
(1 row)
regress=> SELECT * FROM test_table;
x
------
bork
(1 row)
Зверніть увагу , що webui
може SET ROLE
, щоб jim
, навіть коли вже SET ROLE
цифро jane
і навіть якщо jane
НЕ GRANT
ед право приймати на себе роль jim
. SET ROLE
встановлює ваш ефективний ідентифікатор користувача, але він не знімає вашу здатність до SET ROLE
інших ролей, це властивість ролі, яку ви зв'язали, а не вашої поточної ефективної ролі. Отже, ви повинні ретельно контролювати доступ до команд SET ROLE
та RESET ROLE
. AFAIK не має можливості назавжди SET ROLE
встановити з'єднання, по-справжньому стати цільовим користувачем, хоча це, звичайно, було б приємно мати.
Порівняйте:
$ psql -h 127.0.0.1 -U webui regress
Password for user webui:
regress=> SET ROLE jane;
SET
regress=> SET ROLE jim;
SET
regress=> SELECT session_user, current_user;
session_user | current_user
--------------+--------------
webui | jim
(1 row)
до:
$ psql -h 127.0.0.1 -U jane regress
Password for user jane:
regress=> SET ROLE webui;
ERROR: permission denied to set role "webui"
regress=> SET ROLE jim;
ERROR: permission denied to set role "jim"
Це означає, що ви SET ROLE
не точно збігаєтесь із входом у систему як певна роль, що потрібно пам’ятати.
webui
не SET ROLE
може, dbowner
оскільки це не було GRANT
відредаговано правильно:
regress=> SET ROLE dbowner;
ERROR: permission denied to set role "dbowner"
тож само по собі воно досить безсиле, воно може брати на себе права інших користувачів і лише тоді, коли цим користувачам увімкнено доступ до Інтернету.