Ich denke, Sie verschmelzen Authentifizierung und Autorisierung .
Ich stimme voll und ganz zu, dass es sinnvoll ist, das Sicherheitsmodell in der Datenbank beizubehalten, zumal LedgerSMB für den Zugriff mehrerer Clients konzipiert wurde. Sofern Sie nicht vorhaben, eine Middleware-Schicht in drei Ebenen einzurichten, ist es absolut sinnvoll, Benutzer als Datenbankrollen zu verwenden, insbesondere für eine Buchhaltungs-App.
Dies bedeutet nicht, dass Sie Benutzer mit einer von PostgreSQL unterstützten Authentifizierungsmethode gegenüber der Datenbank authentifizieren müssen. Ihre Datenbankbenutzer, Rollen und Berechtigungen können nur dann für die Autorisierung verwendet werden , wenn Sie dies möchten.
So funktioniert es beispielsweise für eine Web-Benutzeroberfläche:
jane
Stellt eine Verbindung zum Web-UI-Server her und authentifiziert sich mit einer beliebigen Methode, z. B. HTTPS X.509-Client-Zertifikat-Handshake und DIGEST-Authentifizierung. Der Server hat jetzt eine Verbindung von einem Benutzer, den er wirklich akzeptiert jane
.
Der Server verbindet sich mit PostgreSQL mit einem festen Benutzernamen / Passwort (oder Kerberos oder was auch immer Sie möchten) und authentifiziert sich gegenüber dem Datenbankserver als Benutzer webui
. Der db server vertraut darauf webui
, seine Benutzer zu authentifizieren, so dass webui
ihm die entsprechenden GRANT
s zugewiesen wurden (siehe unten).
Bei dieser Verbindung SET ROLE jane;
übernimmt der Server die Berechtigungsstufe des Benutzers jane
. Bis der eine RESET ROLE;
oder andere ausgeführt SET ROLE
wird, arbeitet die Verbindung mit den gleichen Zugriffsrechten wie jane
und wird SELECT current_user()
usw. gemeldet jane
.
Der Server behält die Zuordnung zwischen der Datenbankverbindung, auf der er sich befindet SET ROLE
, jane
und der Websitzung für den Benutzer bei jane
und lässt nicht zu, dass diese PostgreSQL-Verbindung von anderen Verbindungen mit anderen Benutzern verwendet wird, ohne dass SET ROLE
dazwischen eine neue Verbindung besteht .
Sie authentifizieren sich jetzt außerhalb des Servers, behalten jedoch die Autorisierung auf dem Server bei. Pg muss wissen, welche Benutzer vorhanden sind, benötigt jedoch keine Kennwörter oder Authentifizierungsmethoden.
Sehen:
Einzelheiten
Der Webui-Server steuert die Ausführung der Abfragen und lässt jane
Raw-SQL nicht laufen (hoffe ich!), jane
Kann also nicht RESET ROLE; SET ROLE special_admin_user;
über die Web-Benutzeroberfläche ausgeführt werden. Zusätzliche Sicherheit würde ich eine Erklärung Filter auf den Server hinzufügen , die abgelehnt SET ROLE
und RESET ROLE
es sei denn , die Verbindung war in oder einen Pool von nicht zugeordneten Verbindungen eingeben.
Es steht Ihnen weiterhin frei, die direkte Authentifizierung gegenüber PG in anderen Clients zu verwenden. Sie können frei mischen und zusammenpassen. Sie müssen GRANT
dem webui
Benutzer lediglich die Rechte für SET ROLE
Benutzer erteilen, die sich über das Web anmelden und diesen Benutzern dann die CONNECT
gewünschten normalen Rechte, Kennwörter usw. erteilen können . Wenn Sie sie nur für das Web verwenden möchten, geben Sie REVOKE
ihre CONNECT
Rechte für die Datenbank (und von public
) an.
Um eine solche Authentifizierung / Autorisierung möglichst einfach aufzuteilen, habe ich eine besondere Rolle assume_any_user
, die ich GRANT
jedem neu angelegten Benutzer zugedacht habe. Ich werde dann GRANT assume_any_user
zu dem echten Benutzernamen, der von Dingen wie einem vertrauenswürdigen Web-Front-End verwendet wird, und gebe ihnen das Recht, jeder Benutzer zu werden, den sie mögen.
Es ist wichtig, assume_any_user
eine NOINHERIT
Rolle zu spielen, damit der webui
Benutzer oder was auch immer selbst keine Rechte hat und nur dann auf die Datenbank einwirken kann, wenn es sich SET ROLE
um einen echten Benutzer handelt. Unter keinen Umständen sollte webui
ein Superuser oder DB-Besitzer sein .
Wenn Sie ein Verbindungspooling durchführen, können Sie SET LOCAL ROLE
die Rolle nur innerhalb einer Transaktion festlegen, sodass Sie nach COMMIT
oder Verbindungen zum Pool zurückgeben können ROLLBACK
. Beachten Sie, dass dies RESET ROLE
immer noch funktioniert. Es ist also immer noch nicht sicher, dass der Client das von ihm gewünschte SQL ausführt.
SET SESSION AUTHORIZATION
ist die verwandte, aber stärkere Version dieses Befehls. Es ist keine Rollenmitgliedschaft erforderlich, aber es handelt sich um einen Superuser-Befehl. Sie möchten nicht, dass sich Ihre Webbenutzeroberfläche als Superuser verbindet. Es kann mit rückgängig gemacht werden RESET SESSION AUTHORIZATION
, SET SESSION AUTHORIZATION DEFAULT
oder SET SESSION AUTHORIZATION theusername
Superuser - Rechte wieder zu erlangen , so dass es entweder kein Privileg-dropping Sicherheitsbarriere ist.
Ein Befehl, der funktioniert hat, SET SESSION AUTHORIZATION
aber irreversibel ist und funktioniert, wenn Sie ein Rollenmitglied, aber kein Superuser sind, wäre großartig. Zu diesem Zeitpunkt gibt es noch keine, aber Sie können Authentifizierung und Autorisierung recht gut trennen, wenn Sie vorsichtig sind.
Beispiel und Erklärung
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;
Jetzt verbinden als webui
. Beachten Sie, dass Sie nicht alles tun , um test_table
aber Sie können SET ROLE
auf jane
und dann können Sie zugreifen 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)
Beachten Sie, dass webui
Dose SET ROLE
zu jim
, auch wenn schon SET ROLE
d zu jane
und obwohl jane
wird nicht GRANT
das Recht ed die Rolle zu übernehmen jim
. SET ROLE
Legt Ihre effektive Benutzer-ID fest, jedoch nicht, dass Sie SET ROLE
andere Rollen zuweisen können. Dies ist eine Eigenschaft der Rolle, mit der Sie verbunden sind, und nicht Ihre aktuelle effektive Rolle. Folglich müssen Sie den Zugriff auf die Befehle SET ROLE
und sorgfältig kontrollieren RESET ROLE
. Es gibt, AFAIK, keine Möglichkeit SET ROLE
für eine dauerhafte Verbindung, wirklich zum Zielbenutzer zu werden, obwohl es sicherlich schön wäre, eine zu haben.
Vergleichen Sie:
$ 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)
zu:
$ 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"
Dies bedeutet, dass SET ROLE
die Anmeldung nicht mit einer bestimmten Rolle identisch ist, was Sie berücksichtigen müssen.
webui
kann nicht SET ROLE
, dbowner
da es nicht so GRANT
richtig bearbeitet wurde:
regress=> SET ROLE dbowner;
ERROR: permission denied to set role "dbowner"
Daher ist es für sich genommen ziemlich machtlos. Es kann nur die Rechte anderer Benutzer übernehmen und nur, wenn für diese Benutzer der Webzugriff aktiviert ist.