Creo que estás combinando autenticación y autorización .
Estoy completamente de acuerdo en que es aconsejable mantener el modelo de seguridad en la base de datos, especialmente porque LedgerSMB está diseñado teniendo en cuenta el acceso de varios clientes. A menos que planee ir a 3 niveles con una capa de middleware, tiene mucho sentido tener usuarios como roles de base de datos, especialmente para algo como una aplicación de contabilidad.
Esto no significa que deba autenticar usuarios en la base de datos utilizando un método de autenticación compatible con PostgreSQL. Los usuarios, roles y subvenciones de su base de datos pueden usarse para autorización solo si lo desea.
Así es como funciona para una interfaz de usuario web, por ejemplo:
jane
se conecta al servidor web ui y se autentica utilizando el método que desee, por ejemplo, el protocolo de enlace de cliente HTTPS X.509 y la autenticación DIGEST. El servidor ahora tiene una conexión de un usuario que acepta es realmente jane
.
El servidor se conecta a PostgreSQL usando un nombre de usuario / contraseña fijos (o Kerberos o lo que quiera), autenticándose en el servidor db como el usuario webui
. El servidor de db confía webui
en autenticar a sus usuarios, por lo que webui
se le ha otorgado el correo electrónico apropiado GRANT
(ver más abajo).
En esa conexión, el servidor utiliza SET ROLE jane;
para asumir el nivel de autorización del usuario jane
. Hasta que se ejecute RESET ROLE;
u otro SET ROLE
, la conexión está operando con los mismos derechos de acceso que jane
y SELECT current_user()
etc. informará jane
.
El servidor mantiene la asociación entre la conexión de base de datos en la que tiene SET ROLE
a jane
y la sesión de la web para el usuario jane
, que no permite que la conexión PostgreSQL para ser utilizado por otras conexiones con otros usuarios sin un nuevo SET ROLE
intermedio.
Ahora se está autenticando fuera del servidor, pero mantiene la autorización en el servidor. Pg necesita saber qué usuarios existen, pero no necesita contraseñas o métodos de autenticación para ellos.
Ver:
Detalles
El servidor webui controla la ejecución de las consultas, y no permitirá jane
ejecutar SQL sin procesar (¡espero!), Por lo jane
que no puede hacerlo a RESET ROLE; SET ROLE special_admin_user;
través de la interfaz de usuario web. Para mayor seguridad, agregaría un filtro de declaración al servidor que rechazó SET ROLE
y, a RESET ROLE
menos que la conexión estuviera o ingresara a un grupo de conexiones no asignadas.
Todavía puede usar la autenticación directa a Pg en otros clientes; Puedes mezclar y combinar libremente. Solo tiene que tener los derechos GRANT
del webui
usuario SET ROLE
para los usuarios que pueden iniciar sesión a través de la web y luego otorgar a esos usuarios los CONNECT
derechos normales , contraseñas, etc. que desee. Si desea hacerlos solo web, REVOKE
sus CONNECT
derechos en la base de datos (y desde public
).
Para hacer una fracción de esa autenticación / autorización fácil que tengo un papel especial assume_any_user
que GRANT
todos los recién creados por el usuario. Luego GRANT assume_any_user
utilizo el nombre de usuario real utilizado por cosas como un front-end web confiable, dándoles los derechos para convertirse en el usuario que deseen.
Es importante hacer assume_any_user
un NOINHERIT
rol, para que el webui
usuario o lo que sea no tenga privilegios por sí mismo y solo pueda actuar en la base de datos una vez que sea SET ROLE
para un usuario real. Bajo ninguna circunstancia debe webui
ser un superusuario o propietario de DB .
Si está agrupando conexiones, puede usarlo SET LOCAL ROLE
para establecer el rol solo dentro de una transacción, de modo que pueda devolver las conexiones al grupo después COMMIT
o ROLLBACK
. Tenga en cuenta que RESET ROLE
todavía funciona, por lo que todavía no es seguro dejar que el cliente ejecute el SQL que quiera.
SET SESSION AUTHORIZATION
es la versión relacionada pero más fuerte de este comando. No requiere membresía de roles, pero es un comando solo de superusuario. No desea que su interfaz de usuario web se conecte como superusuario. Se puede revertir con RESET SESSION AUTHORIZATION
, SET SESSION AUTHORIZATION DEFAULT
o SET SESSION AUTHORIZATION theusername
para recuperar los derechos de superusuario, por lo que tampoco es una barrera de seguridad de privilegio.
Un comando que funcionó de manera similar SET SESSION AUTHORIZATION
pero que era irreversible y que funcionaría si fuera un miembro de rol pero no un superusuario sería genial. En este punto no hay ninguno, pero aún puede separar la autenticación y la autorización bastante bien si tiene cuidado.
Ejemplo y explicacion
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;
Ahora conéctate como webui
. Tenga en cuenta que no puede hacer nada, test_table
pero puede SET ROLE
hacerlo jane
y luego puede acceder a 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)
Tenga en cuenta que webui
puede SET ROLE
que jim
, incluso cuando ya SET ROLE
D para jane
y aunque jane
no se ha GRANT
cado el derecho de asumir el papel jim
. SET ROLE
establece su identificación de usuario efectiva, pero no elimina su capacidad para SET ROLE
otros roles, esa es una propiedad del rol al que se conectó, no su rol efectivo actual. En consecuencia, debe controlar cuidadosamente el acceso a los comandos SET ROLE
y RESET ROLE
. AFAIK, no hay forma SET ROLE
de una conexión permanente , convirtiéndose realmente en el usuario objetivo, aunque ciertamente sería bueno tenerlo.
Comparar:
$ 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)
a:
$ 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"
Esto significa que SET ROLE
no es exactamente lo mismo que iniciar sesión como un rol determinado, algo que debe tener en cuenta.
webui
puede no SET ROLE
a dbowner
, ya que no se ha GRANT
ed ese derecho:
regress=> SET ROLE dbowner;
ERROR: permission denied to set role "dbowner"
así que por sí mismo es bastante impotente, solo puede asumir los derechos de otros usuarios y solo cuando esos usuarios tienen habilitado el acceso web.