简体   繁体   English

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

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

I am trying to obtain the currently authenticated user in the controller for websockets.我正在尝试在 controller 中为 websockets 获取当前经过身份验证的用户。 The problem is, I cannot access the user using SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId() .问题是,我无法使用SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId()访问用户。 I have tried to give Principal as a parameter to the method but it returns principal null.我试图将Principal作为参数提供给该方法,但它返回 principal null。 Security configuration:安全配置:

@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 for websocket: 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);

            }
        });
    }

How can I get the authenticated user?如何获取经过身份验证的用户? I needed it to check when to start the task for the web socket我需要它来检查何时启动 web 套接字的任务

Try to implement ChannelInterceptor, that need to be registrated in Config file (class that implements WebSocketMessageBrokerConfigurer)尝试实现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.

相关问题 在 WebSocket controller 中获取登录用户的 Principal - Get Principal of logged in user in WebSocket controller 如何在ADF模型中检索当前登录用户的窗口? - How to retrieve the current windows logged on user in ADF Model? 如何使用Java检索当前已登录用户的UPN(用户主体名称) - How to retrieve UPN(User principal Name) of current logged in user using Java 如何从 Spring MVC\\Boot Controller 方法中正确检索登录的用户信息? - How to correctly retrieve the logged user information from a Spring MVC\Boot Controller method? 从 Firestore 检索当前登录用户的数据 - Retrieve current logged in user's data from Firestore 如何从当前登录的用户获取数据 - How to get data from current logged user 如何检索当前用户 ID 并放入片段 - How to retrieve current user id and put into a fragment 如何使用OpenID检索当前经过身份验证的用户? - How to retrieve the current authenticated user using OpenID? 如何在Firebase数据库中显示特定当前登录用户的数据? - How to display data of specific current logged in user in Firebase Database? 如何在hibernate事件监听器中获取当前登录用户 - How to get current logged in user in hibernate event listener
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM