Я думаю, что вы объединяете аутентификацию и авторизацию .
Я полностью согласен с тем, что сохранение модели безопасности в БД целесообразно, особенно с учетом того, что LedgerSMB разработан с учетом доступа нескольких клиентов. Если вы не планируете на 3-й уровня с промежуточным слоем имеет идеальный смысл иметь пользователь в качестве ролей базы данных, особенно для что - то вроде учета приложения.
Это не означает, что вы должны аутентифицировать пользователей по базе данных, используя метод аутентификации, поддерживаемый PostgreSQL. Пользователи, роли и гранты вашей базы данных могут быть использованы для авторизации, только если вам это нравится.
Вот как это работает для веб-интерфейса, например:
jane
подключается к серверу веб-интерфейса и проходит проверку подлинности с использованием любого желаемого метода, например, рукопожатия сертификата клиента HTTPS X.509 и аутентификации DIGEST. Сервер теперь имеет соединение от пользователя, которого он принимает на самом деле jane
.
Сервер подключается к PostgreSQL, используя фиксированное имя пользователя / пароль (или Kerberos, или что угодно), аутентифицируя себя на сервере db в качестве пользователя webui
. Сервер db доверяет webui
аутентифицировать своих пользователей, поэтому webui
ему были присвоены соответствующие значения GRANT
(см. Ниже).
В этом соединении сервер использует 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"
так что сам по себе он довольно бессилен, он может принять права других пользователей и только тогда, когда у этих пользователей включен веб-доступ.