我正在开发一个 Java Web 应用程序,其中 Spring 3.2.1 和 Hibernate 4.1.9 绑定(bind)到 Postgres Advanced Server 后端(用于行级安全性)。我试图解决的问题是如何将 webapp 登录用户绑定(bind)到 Hibernate session 。具体来说,如果用户 A 登录,那么我希望与数据库的 webapp 连接使用 A' 凭据(只有这样我才能过滤 A 有权查看/更改的记录)。 Web 应用程序和数据库用户根据同一 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 设置为“session”范围。由于以下原因,我对采取这种方法犹豫不决:
a) 如果数据库连接位于 session 范围内,则我无法使用连接池。 (我想我可能不得不忍受它) b) 我担心将 sessionFactory 设置为 session 范围会扰乱 Hibernate 的缓存机制。
关于如何解决这个问题有什么想法/想法吗?
提前致谢。
最佳答案
另一种替代方法是以非特权用户身份建立所有连接,该用户具有所有用户角色的 NOINHERIT
成员身份。然后,在运行查询之前,为登录用户SET ROLE
。如果由于编程错误而未能SET ROLE
,则危害会降至最低,因为您尚未授予正在连接的非特权用户任何权限,并且它没有继承任何权限,因此它无法做任何事。
使用 servlet 过滤器(如果您对整个请求使用一个连接)、CDI 拦截器、连接池周围的包装器、使用连接池实现提供的 Hook 或各种其他选项来完成此操作应该非常容易确保它总是发生。
如果您可以使用 SET SESSION AUTHORIZATION
来代替,那就太好了,但这需要 super 用户连接。我不建议应用程序使用 super 用户连接,即使它们只是要减少其权限。一个错误可能会造成非常严重的后果。
我wrote in a lot more detail about this in response to a DBA question a while ago .
关于spring - 基于登录用户凭据的 Hibernate 数据源配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15345520/