连接到数据库后切换angular色
是否有可能改变postgresqlangular色的用户在初始连接后与postgres交互时使用?
数据库将用于Web应用程序,我想在连接池上使用表和模式的数据库级规则。 从阅读postgresql文档看来,如果我最初以具有超级用户angular色的用户身份进行连接,则可以切换angular色,但是我更愿意以最低权限进行连接,并根据需要进行切换。 切换时必须指定用户的密码就好了(实际上我更喜欢它)。
我错过了什么?
更新 :我已经按照@Milen的build议尝试了SET ROLE
和SET SESSION AUTHORIZATION
,但是如果用户不是超级用户,那么这两个命令似乎都不起作用:
$ 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
没有inheritanceneil
的权限。
稍后,以webgui身份login:
psql -d some_database -U webgui (enter s3cr3t as password) set role neil;
webgui
不需要superuser
权限。
您想在数据库会话开始时set role
,并在会话结束时重置set role
。 在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); } }
看看“SET ROLE”和“SET SESSION AUTHORIZATION” 。