Java Postgres Hibernate为行级安全设置会话变量
我很难找到关于我遇到的这个问题的信息。我对在我的Postgres db上实现行级安全感兴趣,并且我正在寻找一种能够通过某种形式的拦截器自动设置Postgres会话变量的方法。现在,我知道使用hibernate,您可以使用Java Postgres Hibernate为行级安全设置会话变量,java,postgresql,hibernate,Java,Postgresql,Hibernate,我很难找到关于我遇到的这个问题的信息。我对在我的Postgres db上实现行级安全感兴趣,并且我正在寻找一种能够通过某种形式的拦截器自动设置Postgres会话变量的方法。现在,我知道使用hibernate,您可以使用@Filter和@FilterDef执行行级安全性,但是我想在我的数据库上另外设置策略 执行此操作的一个非常简单的方法是在每次查询之前执行SQL语句SET variable=value,尽管我还没有找到有关此操作的任何信息 这是在spring引导应用程序上使用的,每个请求都将访问
@Filter
和@FilterDef
执行行级安全性,但是我想在我的数据库上另外设置策略
执行此操作的一个非常简单的方法是在每次查询之前执行SQL语句SET variable=value
,尽管我还没有找到有关此操作的任何信息
这是在spring引导应用程序上使用的,每个请求都将访问
变量的请求特定值,因为您的应用程序使用spring,所以您可以尝试通过以下几种方法之一来实现这一点:
春季AOP
在这种方法中,您编写了一条建议,要求spring将其应用于特定的方法。如果您的方法使用@Transactional
注释,则可以在事务启动后立即将建议应用于这些方法
扩展TransactionManager实施
假设您的事务正在使用JpaTransactionManager
public class SecurityPolicyInjectingJpaTransactionManager extends JpaTransactionManager {
@Autowired
private EntityManager entityManager;
// constructors
@Override
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
super.prepareSynchronization(status, definition);
if (status.isNewTransaction()) {
// Use entityManager to execute your database policy param/values
// I would suggest you also register an after-completion callback synchronization
// This after-completion would clear all the policy param/values
// regardless of whether the transaction succeeded or failed
// since this happens just before it gets returned to the connection pool
}
}
}
现在只需配置您的JPA环境以使用自定义的JpaTransactionManager
类
可能还有其他方法,但我已经探讨过这两种方法。有几种方法可以实现这一点,但它们都因您可能使用的其他框架而异。告诉我,您的应用程序是使用Spring还是编写为在WildFly这样的应用程序服务器上运行?@Naros该应用程序使用Spring。@NTL您能回答:我今天和明天都会研究这种方法,谢谢。这在很大程度上似乎有效,但我遇到了一个新问题。我已经定义了一个@Repository
,该扩展了分页和排序存储库
,并在其中定义了以下签名:Boolean existemplatebynameignorecase(字符串名)代码>。如果我先调用此函数,则会忽略SecurityPolicyInjectingJpaTransactionManager
,并且不会执行我在prepareSynchronization
中的逻辑。更新我以前的注释。通过注释布尔existemplatebynameignorecase(字符串名),解决了该问题使用@Transactional
的code>方法。我的问题是,这是否可以在不指定注释的情况下对每个查询执行?传统上,存储库调用由服务方法或控制器方法包装,该方法使用@Transactional
进行注释。您永远不希望以这种方式注释存储库方法,因为单个原子操作可能涉及多个存储库。例如,要创建订单,我可能需要从ProductRepository
获取信息,创建订单,然后使用OrderRepository
保存它。整个操作是单个原子操作,所有操作都应关联到单个数据库事务。