gpt4 book ai didi

postgresql - 连接数据库后切换角色

转载 作者:行者123 更新时间:2023-11-29 11:05:42 28 4
gpt4 key购买 nike

是否可以更改用户在初始连接后与 postgres 交互时使用的 postgresql 角色?

数据库将在 Web 应用程序中使用,我想在具有连接池的表和模式上使用数据库级规则。通过阅读 postgresql 文档,如果我最初以具有 super 用户角色的用户身份连接,我似乎可以切换角色,但我更愿意最初以具有最小权限的用户身份连接并根据需要切换。切换时必须指定用户密码就可以了(事实上我更喜欢它)。

我错过了什么?

更新:我已经按照@Milen 的建议尝试了 SET ROLESET SESSION AUTHORIZATION 但是如果用户不是 super 用户:

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

您想在数据库 session 开始时设置角色,并在 session 结束时重置它。在 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);
}
}

关于postgresql - 连接数据库后切换角色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2998597/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com