加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 连接到数据库后切换角色

发布时间:2020-12-13 16:43:56 所属栏目:百科 来源:网络整理
导读:是否可以更改用户在初始连接后与postgres进行交互时使用的postgresql角色? 数据库将在Web应用程序中使用,我想对连接池的表和模式使用数据库级规则。从阅读postgresql文档,我似乎可以切换角色,如果我最初作为一个用户与超级用户角色连接,但我宁愿最初连
是否可以更改用户在初始连接后与postgres进行交互时使用的postgresql角色?

数据库将在Web应用程序中使用,我想对连接池的表和模式使用数据库级规则。从阅读postgresql文档,我似乎可以切换角色,如果我最初作为一个用户与超级用户角色连接,但我宁愿最初连接作为一个用户具有最小的权限,并根据需要切换。在切换时必须指定用户的密码会很好(事实上我更喜欢它)。

我缺少什么?

更新:我尝试了SET ROLE和SET SESSION AUTHORIZATION,如@Milen建议的,但如果用户不是超级用户,这两个命令似乎都不工作:

$ 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
--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不需要超级用户权限。

您希望在数据库会话开始时设置角色,并在会话结束时将其重置。在Web应用程序中,这对应于从数据库连接池获取连接并释放它。这里有一个使用Tomcat的连接池和Spring Security的例子:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读