2

我正在开发一个 Java webapp,其中 Spring 3.2.1 和 Hibernate 4.1.9 绑定到 Postgres Advanced Server 后端(用于行级安全性)。我要解决的问题是如何将 webapp 登录用户绑定到 Hibernate 会话。具体来说,如果用户 A 登录,那么我希望 webapp 与数据库的连接使用 A' 凭据(只有这样我才能过滤 A 有权查看/更改的记录)。Webapp 和数据库用户在同一个 ldap 服务器上进行验证。

我的配置信息如下:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="annotatedClasses">
        <list>
            <value>com.mycom.proj.model.A</value>
            <value>com.mycom.proj.model.B</value>
            <value>com.mycom.proj.model.C</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${db.hibernate.dialect}</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
        </props>
    </property>
</bean>

基于上述配置,dataSource 和 sessionFactory bean 是单例的。

我可以采取的一种方法是将 dataSource 和 sessionFactory 设置为“会话”范围。我犹豫要不要采用这种方法,原因如下:

a)如果数据库连接在会话范围内,那么我不能使用连接池。(我想我可能不得不忍受它) b)我担心将 sessionFactory 设置为会话范围会破坏 Hibernate 的缓存机制。

关于如何解决这个问题的任何想法/想法?

提前致谢。

4

2 回答 2

2

另一种选择是将所有连接作为具有NOINHERIT所有用户角色成员身份的非特权用户进行。然后SET ROLE在运行查询之前登录用户。如果SET ROLE由于编程错误而失败,则伤害会最小化,因为您没有授予您正在连接的非特权用户任何权利,并且它没有继承任何权利,因此它不能做任何事情。

使用 servlet 过滤器(如果您对整个请求使用一个连接)、CDI 拦截器、连接池周围的包装器、使用连接池实现提供的钩子或各种其他选项来确保它应该很容易做到这一点总是发生。

如果您可以使用它会很好SET SESSION AUTHORIZATION,但这需要超级用户连接。我不建议应用程序使用超级用户连接,即使它们只是要降低其权限。一个错误可能会造成非常严重的后果。

不久前,我在回答一个 DBA 问题时对此进行了更详细的描述

于 2013-03-11T22:50:54.500 回答
1

通常连接池处理每个用户的池连接,因此您只需要一个适配器来将getConnection()调用重定向到getConnection(user, passwd).

Spring提供了一个,见:org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter

Datasource例如,您可以在登录过滤器中的viasetCredentialsForCurrentThread()方法上设置凭据。

于 2013-03-11T20:48:41.327 回答