我正在使用
MessageListener
实现从 RabbitMQ 接收消息,但 securityContextHolder.getContext()
仅在 null
中返回 onMessage
,但它对于应用程序的其余部分运行良好:
@Override
public void onMessage(Message message) {
Gson gson = new Gson();
ControleResult resultControle = gson.fromJson(new String(message.getBody()), Facture.class);
Optional<Facture> optional = dossierDao.findById(resultControle.getId());
Facture facture= null;
if (optional.isPresent()) {
facture= optional.get();
}
factureDao.save(facture);
log.info("USER " + getLoggedInUserName());
}
private String getLoggedInUserName() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
Object principal = authentication.getPrincipal();
if (principal instanceof UserDetails) {
ConnectedUser userDetails = (ConnectedUser) authentication.getPrincipal();
return String.format("%s %s",userDetails.getUsername(), userDetails.getUserlastname());
}
}
return null;
}
SecurityContextHolder.getContext()
默认使用 ThreadLocal
变量来存储 Authentication
对象。
当 RabbitMQ 监听器调用
onMessage()
函数时,它将在新的线程中调用。每个新的 Thread
都会获得自己的 ThreadLocal
变量实例,因此命名为“本地”线程。这意味着它在 Web 应用程序中没有当前登录用户的上下文。
有关不同安全上下文持有者策略的更多信息,请参阅我对this问题的回答。