Las veces que me toca dar el curso a mi, me gusta explicar a fondo lo más que puedo acerca de roles.
Se nos dice que un rol, es asignado por default a un usuario. Un rol, puede ser asegurado de manera adicional, que por default, no trae seguridad alguna.
Entonces, partiendo de la teoría, un rol puede ser creado con la siguiente seguridad:
* Ninguna (Default)
* Password
* External
* Global
Por falta de hardware/software, no puedo demostrar la seguridad Global, pero las demás sí.
Empecemos por crear un usuario, solo para no perder la costumbre, crearé un usuario identificado a nivel sistema operativo.
C:\>sqlplus "/ AS SYSDBA"
Conectado a:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> CREATE USER "OPS$HUGO-WIN\HUGO" IDENTIFIED externally;
Usuario creado.
SQL> GRANT CONNECT TO "OPS$HUGO-WIN\HUGO";
Concesión terminada correctamente.
Ahora nos conectamos como el usuario creado, identificado de manera externa, y validamos el primer rol asignado "CONNECT"
SQL> conn /
Conectado.
SQL> show user
USER es "OPS$HUGO-WIN\HUGO"
SQL> select * from session_roles;
ROLE
------------------------------
CONNECT
Aquí validamos dos cosas, la primera es que el rol de create session viene implícito en el connect, ya que de otra forma no hubieramos podido crear la sesión; y lo segundo es que el rol asignado, está activo por default.
Ahora crearemos un rol identificado por un password
SQL> conn / as sysdba
Conectado.
SQL> CREATE role dba_pass IDENTIFIED BY supersecreto;
Rol creado.
SQL> GRANT DBA TO dba_pass;
Concesión terminada correctamente.
SQL> GRANT dba_pass TO "OPS$HUGO-WIN\HUGO";
Concesión terminada correctamente.
Ya que se tiene asignado al usuario el nuevo rol, nos conectamos como el usuario
SQL> conn /
Conectado.
SQL> show user
USER es "OPS$HUGO-WIN\HUGO"
SQL> select * from session_roles;
ROLE
------------------------------
CONNECT
DBA_PASS
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
SCHEDULER_ADMIN
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
XDBADMIN
XDBWEBSERVICES
OLAP_DBA
17 filas seleccionadas.
Como vemos, el rol está asignado por default, y no nos pide el password nunca, lo que debemos hacer si es que queremos que el usuario use el password, es quitarlo del default del usuario.
SQL> conn / as sysdba
Conectado.
SQL> ALTER USER "OPS$HUGO-WIN\HUGO"
2 DEFAULT ROLE ALL EXCEPT dba_pass;
Usuario modificado.
SQL> conn /
Conectado.
SQL> show user
USER es "OPS$HUGO-WIN\HUGO"
SQL> select * from session_roles;
ROLE
------------------------------
CONNECT
Ahora intentamos usar el rol, validando que se requiere un password.
SQL> show user
USER es "OPS$HUGO-WIN\HUGO"
SQL> SET role dba_pass;
SET role dba_pass
*
ERROR en línea 1:
ORA-01979: falta la contraseña para el rol 'DBA_PASS' o no es válida
SQL> SET role dba_pass IDENTIFIED BY supersecreto;
Rol definido.
SQL> SELECT COUNT(1)
2 FROM v$session;
COUNT(1)
----------
15
Ahora crearemos un rol identificado a través de un procedimiento.
Lo primero es crear el procedimiento.
SQL> conn / as sysdba
Conectado.
SQL> CREATE OR REPLACE PROCEDURE sec_roles
2 authid CURRENT_USER AS
3 usuario VARCHAR2(50);
4 BEGIN
5 usuario := LOWER((sys_context('userenv', 'session_user')));
6 DBMS_OUTPUT.PUT_LINE(usuario);
7 IF UPPER(usuario) = 'OPS$HUGO-WIN\HUGO' THEN
8 dbms_session.set_role('DBA_PROC');
9 ELSE
10 NULL;
11 END IF;
12 END;
13 /
Procedimiento creado.
Es importante el punto de AUTHID, debe estar en current user si no, no funcionaría. Ya que se tiene el procedimiento creado, continuamos con el resto del rol y grants necesarios al usuario.
SQL> GRANT EXECUTE ON sec_roles TO "OPS$HUGO-WIN\HUGO";
Concesión terminada correctamente.
SQL> CREATE role dba_proc IDENTIFIED USING sys.sec_roles;
Rol creado.
SQL> GRANT DBA TO dba_proc;
Concesión terminada correctamente.
SQL> GRANT EXECUTE ON sys.dbms_session TO "OPS$HUGO-WIN\HUGO";
Concesión terminada correctamente.
Es necesario que el usario que queremos que use el rol, tenga un grant al procedimiento de sys.sec_roles, y tambien permisos de ejecución en sys.dbms_session.
SQL> conn /
Conectado.
SQL> select * from session_roles;
ROLE
------------------------------
CONNECT
SQL> exec sys.sec_roles;
ops$hugo-win\hugo
Procedimiento PL/SQL terminado correctamente.
SQL> select * from session_roles;
ROLE
------------------------------
DBA_PROC
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
SCHEDULER_ADMIN
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
XDBADMIN
XDBWEBSERVICES
OLAP_DBA
16 filas seleccionadas.
SQL>
Hay que notar que al usuario "ops$hugo-win\hugo" jamás se le dio un grant sobre el ROL, el ROL lo obtiene con la ejecución del procedimiento.
¿Alguien tendrá un ejemplo de la autenticación global para compartir?
1 comentario:
gracias x la info, muy interesante.
Publicar un comentario