我有一个用@KafkaListener
注释的豆子,在这个豆子里,我计划通过SecurityContextHolder
获取登录的用户凭据。
但是,SecurityContextHolder.getContext().getAuthentication()
给了我一个null
对象,可能是因为它以不同的thread
运行。
在这种情况下,有没有办法将SecurityContext
从ThreadLocal
传播到另一个线程?在我的Spring Boot
配置中可以轻松完成吗?
下面是示例代码:
@Component
@Slf4j
public class MessageConsumer {
private final MessageService messageService;
@Autowired
public MessageConsumer(final MessageService service) {
messageService = service;
}
@KafkaListener(topics = "myTopic")
public void receive(final List<Message> message) {
messageService.consumerAnStoreMessage(message, SecurityContextHolder.getContext().getAuthentication());
}
}
例如,SecurityContext的身份验证表示调用Web服务的用户,网站的页面...等。。。
当您收听 kafka 消息时,应该使用哪个用户的上下文?我不认为你想做的事情真的有意义。
我迟到了。也许这是有意义的,如果你有一个从其他系统(CDC)复制更改的应用程序,并且你想要设置,而不是所有更改都来自特定用户。
在这种情况下,SpringSecurity 允许您配置 SecurityContextHolder 模式(参见 https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/context/SecurityContextHolder.html)。您可以使用以下内容设置为全局:SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL)
另一种选择是在用 @KafkaListener 注释的 de 方法中进行身份验证