有没有办法阻止Hibernate envers只审计一次数据库操作?

问题描述 投票:0回答:1

堆栈

  1. spring boot 2.7.15
  2. spring-boot-starter-data-jpa 2.7.15
  3. spring-data-envers 2.7.15

我有以下实体:

@Audited
@Entity
@EntityListeners(AuditingEntityListener.class)
public class MyUser{
}

使用审核员配置类

JpaAuditingConfiguration
:

@Configuration
@AutoConfigureAfter(name = "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration")
@EnableJpaAuditing
public class JpaAuditingConfiguration {

    @Bean
    public AuditorAware<Long> auditorAware(MyUserService myUserService ) {
        return myUserService::getCurrentUserId;
    }

}

还有

MyUserService
班:

@Service
@RequiredArgsConstructor
public class MyUserService {

    public Optional<Long> getCurrentUserId() {
         Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof OAuth2AuthenticatedPrincipal) {
           // logic here
        }
        return Optional.empty();
    }
}

我的问题来了:我有一个来自内部授权/身份验证框架的 Bean,它设置/丰富 spring 的

Authentication
对象,并且当用户在 UI 中登录时触发它。在这个 bean 方法中,一个实体被修改并持久化到数据库中:

 public Set<String> retrieveUserAuthorities(String username) {
        Optional<MyUser> userOptional = userRepository.findByUsername(username);
        
        if (userOptional.isPresent()) {
            MyUser user = userOptional.get();

            // different setters for user
            myUserService.saveUser(user); // <--- here is the problem

            return ...
        }

      // ...
    }

问题:

基本上,问题在于实体在设置Authentication对象之前

被持久化到数据库中,因此当触发审计流程并到达方法
getCurrentUserId()
(其中
SecurityContextHolder.getContext().getAuthentication()
为空)时会得到一个NPE。

就我而言,我希望

此数据库操作不被持久化,但该实体上的其他操作要持久化,因此删除Audited

@EntityListeners
不是一个选项。

hibernate spring-security spring-data-jpa spring-data hibernate-envers
1个回答
0
投票
也许在访问

principal

 对象之前进行简单的空检查就可以解决问题。

public Optional<Long> getCurrentUserId() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && principal instanceof OAuth2AuthenticatedPrincipal) { // logic here } return Optional.empty(); }
在 Spring Security 中发现 

authentication

 对象为 
null
 并不奇怪。

© www.soinside.com 2019 - 2024. All rights reserved.