Я думаю, что вы объединяете аутентификацию и авторизацию .
Я полностью согласен с тем, что сохранение модели безопасности в БД целесообразно, особенно с учетом того, что 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"
так что сам по себе он довольно бессилен, он может принять права других пользователей и только тогда, когда у этих пользователей включен веб-доступ.