2010-06-08 19 views
36

È possibile modificare il ruolo postgresql che un utente sta utilizzando durante l'interazione con postgres dopo la connessione iniziale?Cambia ruolo dopo la connessione al database

I database verranno utilizzati in un'applicazione Web e mi piacerebbe utilizzare le regole a livello di database su tabelle e schemi con pool di connessioni. Dalla lettura della documentazione postgresql sembra che io possa cambiare ruolo se mi connetto originariamente come utente con il ruolo di superuser, ma preferirei inizialmente connettermi come utente con permessi minimi e passare se necessario. Dover specificare la password dell'utente quando il passaggio va bene (in effetti preferirei farlo).

Cosa mi manca?

Aggiornamento: Ho provato sia SET ROLE e SET SESSION AUTHORIZATION come suggerito da @Milen tuttavia né il comando sembra funzionare se l'utente non è un superutente:

$ psql -U test 
psql (8.4.4) 
Type "help" for help. 

test=> \du test 
      List of roles 
Role name | Attributes | Member of  
-----------+------------+---------------- 
test  |   | {connect_only} 

test=> \du test2 
      List of roles 
Role name | Attributes | Member of  
-----------+------------+---------------- 
test2  |   | {connect_only} 

test=> set role test2; 
ERROR: permission denied to set role "test2" 
test=> \q 

risposta

7

Date un'occhiata a "SET ROLE" e "SET SESSION AUTHORIZATION".

+0

ho provato entrambi i comandi senza alcun risultato, se l'utente si collega non è un superutente ricevo permesso negato errori. Ho aggiornato la domanda con ulteriori informazioni –

+1

Credo che il tuo utente debba essere un membro del RUOLO che vuoi già impostare e avere la proprietà NOINHERITS sul suo utente in modo che non siano predefiniti. Allora dovresti essere intensificato e de-escalation. Ma devono già essere membri del RUOLO. – rfusca

30
--create a user that you want to use the database as: 

create role neil; 

--create the user for the web server to connect as: 

create role webgui noinherit login password 's3cr3t'; 

--let webgui set role to neil: 

grant neil to webgui; --this looks backwards but is correct. 

webgui è ora nel gruppo neil, così webgui può chiamare set role neil. Tuttavia, webgui non ha ereditato le autorizzazioni di neil.

Più tardi, come login webgui:

psql -d some_database -U webgui 
(enter s3cr3t as password) 

set role neil; 

webgui non ha bisogno superuser permesso per questo.

Si desidera set role all'inizio di una sessione del database e reimpostarlo alla fine della sessione. In un'app Web, ciò corrisponde a ottenere una connessione dal pool di connessione del database e al rilascio, rispettivamente. Ecco un esempio utilizzando pool di connessioni di Tomcat e Sicurezza Primavera:

public class SetRoleJdbcInterceptor extends JdbcInterceptor { 

    @Override 
    public void reset(ConnectionPool connectionPool, PooledConnection pooledConnection) { 

     Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 

     if(authentication != null) { 
      try { 

       /* 
        use OWASP's ESAPI to encode the username to avoid SQL Injection. Can't use parameters with SET ROLE. Need to write PG codec. 

        Or use a whitelist-map approach 
       */ 
       String username = ESAPI.encoder().encodeForSQL(MY_CODEC, authentication.getName()); 

       Statement statement = pooledConnection.getConnection().createStatement(); 
       statement.execute("set role \"" + username + "\""); 
       statement.close(); 
      } catch(SQLException exp){ 
       throw new RuntimeException(exp); 
      } 
     } 
    } 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 

     if("close".equals(method.getName())){ 
      Statement statement = ((Connection)proxy).createStatement(); 
      statement.execute("reset role"); 
      statement.close(); 
     } 

     return super.invoke(proxy, method, args); 
    } 
} 
Problemi correlati