sql >> データベース >  >> RDS >> PostgreSQL

データベースに接続した後、役割を切り替えます

    --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 現在、neilにあります グループなので、webgui set role neilを呼び出すことができます 。ただし、webgui neilを継承しませんでした の権限。

    後で、webguiとしてログインします:

    psql -d some_database -U webgui
    (enter s3cr3t as password)
    
    set role neil;
    

    webgui superuserは必要ありません これに対する許可。

    set roleしたい データベースセッションの開始時に、セッションの終了時にリセットします。 Webアプリでは、これはそれぞれデータベース接続プールから接続を取得して解放することに対応します。次に、Tomcatの接続プールとSpringSecurityを使用した例を示します。

    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);
        }
    }
    


    1. SQLiteの英数字を含む行を返す

    2. トランザクション内(SQL Server内)で複数のDDLステートメントを実行することは可能ですか?

    3. 時系列データベースとは何ですか?

    4. OracleのBFILE列からBLOBを取得する