我正在使用Grails Audit Logging插件,但我的一些(~1.5%)Audit Log记录与不正确的参与者(用户)关联。此API是多租户的,其中许多记录不可能由正在记录的参与者完成(因为它们在不同的组织中)。这似乎主要发生在INSERT
和UPDATE
记录上。
据我所知,记录的操作来自@Subscriber
方法,这些方法是从堆栈更上层的事件发布器调用的。
例如,当用户提交additionalPhoto
时,事件发布者调用compareToAdditionalPhoto
:
@Publisher(Event.ADDITIONAL_PHOTO_CREATED)
@Transactional(rollbackFor = Throwable.class)
AdditionalPhoto create(AdditionalPhoto additionalPhoto) {
additionalPhoto.expirationDate = new Date(System.currentTimeMillis() + additionalPhoto.additionalPhotoType.timeToLive)
additionalPhoto.validate()
if (additionalPhoto.hasErrors())
throw new InvalidResourceException(additionalPhoto.errors)
deletePriorAdditionalPhotos(additionalPhoto)
additionalPhoto.save()
return additionalPhoto
}
@Transactional
@Subscriber(Event.ADDITIONAL_PHOTO_CREATED)
void compareToPhoto(AdditionalPhoto additionalPhoto) {
compareFaces(additionalPhoto)
}
void compareFaces(AdditionalPhoto additionalPhoto, Photo photo = null) {
log.debug("comparing faces for additionalPhoto #$additionalPhoto.id")
if (!additionalPhoto.additionalPhotoType.enableFacialRecognition) return
sleep(asyncDelay)
photo = photo ?: additionalPhoto.person.currentPhoto
additionalPhoto.facialRecognitionScore = rekognitionService.compareFaces(photoService.fetchBytes(photo), fetchBytes(additionalPhoto))
if (additionalPhoto.facialRecognitionScore == NO_FACE_DETECTED) {
log.error("No face detected in either Photo #$photo.id or Additional Photo #$additionalPhoto.id for $additionalPhoto.person.email")
}
additionalPhoto.save()
}
审核日志中记录的执行元属于另一个组织,不可能已启动此方法调用。但是,执行元在发出其他请求时已主动登录到应用程序。
看起来Hibernate可能将订阅者执行的操作搭载到另一个活动会话上,并错误地将其归属于参与者。这是可能的吗?由于大多数记录都被正确保存,因此调试起来很棘手。
我真的很感激任何建议,如何避免这种情况发生,请让我知道,如果任何更多的细节是需要在我的问题。谢谢!
1条答案
按热度按时间xa9qqrwz1#
在Grails审计日志插件github repo的帮助下,我解决了这个问题!
这个问题是由
SecurityContextHolder
策略MODE_INHERITABLETHREADLOCAL
引起的。这是3.2.1到4.0.0之间的审计日志插件版本的默认设置,但不建议在池环境中使用(请参阅Spring Security repo上的讨论)。我们升级到4.0.1,将策略切换为MODE_THREADLOCAL
,这修复了这个问题。