我正在尝试将SET SESSION encrypt.key='some_key'设置为数据库查询或连接。
问题是我在我的模型类中有以下列定义
@Column转换器(forColumn= "first_name",read = "pgp_sym_decrypt(first_name,current_setting(‘encrypt.key’)“),read= "pgp_sym_encrypt(?,current_setting(‘encrypt.key’)”) @Column(name = "first_name",columnDefinition = "bytea")私有字符串firstName;
当我们在encrypt.key文件中直接设置postgres.conf文件时,上面的操作是有效的,但我们的需求是从spring属性文件中配置encrypt.key。
我试过的东西。
自定义转换器类的
@Override
protected void prepareSynchronization(DefaultTransactionStatus status,TransactionDefinition definition) {
super.prepareSynchronization(status, definition);
if (status.isNewTransaction()) {
final String query = "SET encrypt.key='" + encryptKey + "'";
entityManager.createNativeQuery(query).executeUpdate();
}
log.info("Encrypt Key : {}", entityManager.createNativeQuery("SElECT current_setting('encrypt.key')").getSingleResult());
}
}当我调用普通的JPA方法时,上面的encrypt.key不起作用,并且在normal中,CustomTransactionManager类没有被设置为CustomTransactionManager类。
任何正确的指导都会对我有很大帮助。
发布于 2022-11-16 14:02:00
因为我创建了CustomTransactionManager扩展JpaTransactionManager
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionStatus;
import javax.persistence.EntityManager;
@Component
@Slf4j
@Primary
@Qualifier(value = "transactionManager")
public class CustomTransactionManager extends JpaTransactionManager {
@Autowired
private EntityManager entityManager;
@Value("${database.encryption.key}")
private String encryptKey;
@Override
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
super.prepareSynchronization(status, definition);
if (status.isNewTransaction()) {
final String query = "SET SESSION encrypt.key='" + encryptKey + "'";
entityManager.createNativeQuery(query).executeUpdate();
}
}
}当我使用普通的方法时,上面并没有被调用。例如,
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByFirstName(String firstName);
}在Repository类中添加@Transactional确实覆盖了框架逻辑,该框架逻辑为所有存储库bean在后台创建共享事务。这使得即使使用存储库方法也可以调用我的CustomTransactionManager。
我最初认为添加事务注释是过分的,但发现它也是在框架级别自动创建的,因此手动添加它本身没有额外的内存占用空间,但是您在CustomTransactionManager类中编写的代码/查询将添加所需的请求占用空间。
因此,我最后在其域(表)具有加密列的所有存储库类上添加了@Transactional注释。
对于我的用例,这是使用Spring在Azure数据库服务上进行列级加密的最灵活的解决方案,因为我们不能从Azure在那里添加自定义环境变量,而且直接添加到postgres.conf文件也是不可能的,因为它是一个SAAS服务。
https://stackoverflow.com/questions/74345585
复制相似问题