简体   繁体   中英

Send notification to authenticated user over spring websocket, sockJs and STOMP

I have a JWT based application, secured by spring security. Everything is secured and working fine. Also, application exposes a websocket url (localhost:8080/ws), to which users can subscribe ("/realtime") and receive generic updates ie every user, authenticated or unauthenticated, will receive updates.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/realtime");

        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOrigins("*")
                .withSockJS();

    }

}

Client code:

//private _channel = "/realtime";
  constructor(){
    this.connect();
  }
  public connect() : void {
      let self = this;
      var token = localStorage.getItem("token");//get jwt from storage
      self._webSocketUrl = "http://localhost:8080/ws";
      //let webSocket = new WebSocket(this._webSocketUrl);//without sockjs
      let webSocket = new SockJS(this._webSocketUrl);//with sockjs
      self._stompClient = Stomp.over(webSocket);
      self._stompClient.connect({}, function (frame) {
        self._stompClient.subscribe("/realtime", function (stompResponse) {

              console.log("got data from server");
              self._stompSubject.next(stompResponse);
          });
      });
  }

All of this is working fine. Now, I need to send notifications to specific authenticated user whenever something of their interest happens on the server. So, I don't receive any messages from users ever. Whenever an authenticated user needs to send a request, he can do that through rest endpoints, not websocket. So, once he has logged in, connected to /ws endpoint and subscribed to "/realtime destination, he is done. Now, its my job to send notifications to them whenever available for a specific user. It's kind of one way (server to client) communication over websocket. This will change in the future.

So, whenever I have something for an authenticated user, say, user123@gmail.com, how do I send a notification to him through websocket?

I have gone through many links and question on stackoverflow, but could not find anything that works.

I was able to get this working by doing the following:

  1. Use authentication principal in the subscription, for example

     self._stompClient.subscribe("/realtime/" + userName, function (stompResponse) { console.log("got data from server"); self._stompSubject.next(stompResponse); }); 

    });

  2. Send to the user as

     simpMessagingTemplate.convertAndSendToUser(userName, "/realtime/", message); 

Please note this solution may not provide appropriate security controls . Please review https://docs.spring.io/spring-security/site/docs/current/reference/html/websocket.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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