【问题标题】:Postgres Hibernate set session variables for row level securityPostgres Hibernate 为行级安全设置会话变量
【发布时间】:2019-09-17 03:14:40
【问题描述】:

我无法找到有关我遇到的这个问题的信息。我有兴趣在我的 Postgres 数据库上实现行级安全性,我正在寻找一种能够通过某种形式的拦截器自动设置 postgres 会话变量的方法。现在,我知道通过休眠,您可以使用@Filter@FilterDef 进行行级安全,但是我想另外在我的数据库上设置策略。

执行此操作的一个非常简单的方法是在每次查询之前执行 SQL 语句 SET variable=value,尽管我无法找到任何相关信息。

这是在 spring-boot 应用程序上使用的,并且每个请求都可以访问variable 的特定于请求的值。

【问题讨论】:

  • 有几种方法可以实现这一点,但它们都因您可能使用的其他框架而异。告诉我,您的应用程序是使用 Spring 还是编写为在 WildFly 等应用程序服务器上运行?
  • @Naros 应用程序正在使用 Spring。

标签: java postgresql hibernate


【解决方案1】:

由于您的应用程序使用 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 类。


可能还有其他人,但这是我探索过的两个。

【讨论】:

  • 今天和明天我会研究这种方法,谢谢。
  • 这似乎在大多数情况下都有效,但是我遇到了一个新问题。我已经定义了一个@Repositoryextends PagingAndSortingRepository,并在其中定义了以下签名:Boolean existsTemplateByNameIgnoreCase(String name);。如果我先调用它,那么 SecurityPolicyInjectingJpaTransactionManager 会被忽略,我在 prepareSynchronization 中的逻辑不会被执行。
  • 更新我之前的评论。通过使用@Transactional 注释Boolean existsTemplateByNameIgnoreCase(String name); 方法来解决该问题。我的问题是,这是否可以在不指定注释的情况下为每个查询完成?
  • 传统上,存储库调用由服务方法或使用@Transactional 注释的控制器方法包装。您永远不想以这种方式注释存储库方法,因为单个原子操作可能涉及多个存储库。例如,要创建订单,我可能需要从ProductRepository 获取信息,创建订单然后使用OrderRepository 保存它。这整个操作是一个单一的原子操作,应该都与单个数据库事务相关联。
猜你喜欢
  • 2013-01-27
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-11
相关资源
最近更新 更多