繁体   English   中英

如何在 websocket controller 中检索当前登录用户

[英]How to retrieve the current logged in user in a websocket controller

我正在尝试在 controller 中为 websockets 获取当前经过身份验证的用户。 问题是,我无法使用SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId()访问用户。 我试图将Principal作为参数提供给该方法,但它返回 principal null。 安全配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/connect").setAllowedOrigins("*");
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic/messages");
        registry.setApplicationDestinationPrefixes("/ws");
    }

}

Controller 用于 websocket:

@Controller
public class MessageController {

    @Autowired
    private Consumer consumer;

    @Autowired
    private Utils utils;

    @Autowired
    private PersonService personService;

    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;
    String destination = "/topic/messages";

    ExecutorService executorService =
            Executors.newFixedThreadPool(1);
    Future<?> submittedTask;

    @MessageMapping("/start")
    public void startTask(Principal principal){

        // Here, I would like to get the logged in user
        // If I use principal like this: principal.getName() => NullPointerException


        if ( submittedTask != null ){
            simpMessagingTemplate.convertAndSend(destination,
                    "Task already started");
            return;
        }
        simpMessagingTemplate.convertAndSendToUser(sha.getUser().getName(), destination,
                "Started task");
        submittedTask = executorService.submit(() -> {
            while(true){
simpMessagingTemplate.convertAndSend(destination,
//                            "The calculated value " + val + " is equal to : " + max);

            }
        });
    }

如何获取经过身份验证的用户? 我需要它来检查何时启动 web 套接字的任务

尝试实现ChannelInterceptor,需要在Config文件中注册(实现WebSocketMessageBrokerConfigurer的类)

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer  {

    private final ChannelInterceptor serverPushInBoundInterceptor;

    @Autowired
    public WebSocketConfig(@Qualifier("serverPushInBoundInterceptor") ChannelInterceptor serverPushInBoundInterceptor) {
        this.serverPushInBoundInterceptor = serverPushInBoundInterceptor;
    }

    ....

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(serverPushInBoundInterceptor);
    }
}

@Component("serverPushInBoundInterceptor")
public class ServerPushInBoundInterceptor implements ChannelInterceptor {
    private static final Logger log = LoggerFactory.getLogger(ServerPushInBoundInterceptor.class);


    @Override
    @SuppressWarnings("NullableProblems")
    public Message<?> postReceive(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

        if (StompCommand.CONNECT.equals(Objects.requireNonNull(accessor).getCommand())) {
            List<String> authorization = accessor.getNativeHeader("Authorization");
            if (authorization != null && !authorization.isEmpty()) {
                String auth = authorization.get(0).split(" ")[1];
                System.out.println(auth);
                try {

                    // find Principal
                    Principal principal = ...
                    accessor.setUser(new UsernamePasswordAuthenticationToken(principal, principal.getCredentials(), principal.getAuthorities()));

                } catch (Exception exc) {
                    log.error("preSend", exc);
                }
            }
        }

        return message;
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM