How to connect web sockets between Spring Boot and Angular with Spring Security?

254 views Asked by At

I'm working on a real time chat project using web sockets in Spring Boot and Angular. i'm using Spring Security in my api.

Here is my WebSocketConfig in api :

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/socket")
                .setAllowedOriginPatterns("*")
                .withSockJS();
    }
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app")
                .enableSimpleBroker("/message");
    }
}

and here is my controller :

@Controller
public class WebSocketController {

    private final SimpMessagingTemplate template;

    @Autowired
    WebSocketController(SimpMessagingTemplate template){
        this.template = template;
    }

    @MessageMapping("/send/message")
    public void sendMessage(String message){
        System.out.println(message);
        this.template.convertAndSend("/message",  message);
    }
}

When I send a request with Postman on 'http://localhost:8080/socket, it works

Now, this is my Angular service to set up the connection :

import { Injectable } from '@angular/core';
declare var SockJS: any;
declare var Stomp: any;

@Injectable({
  providedIn: 'root',
})
export class WebSocketService {
  
  constructor() {
    this.initializeWebSocketConnection();
  }
  stompClient: any;
  msg: string[] = [];
  initializeWebSocketConnection() {
    const serverUrl = 'http://localhost:8080/socket';
    const ws = new SockJS(serverUrl);
    this.stompClient = Stomp.over(ws);
    const that = this;
    this.stompClient.connect({}, function(frame: any) {
      that.stompClient.subscribe('/message', (message: any) => {
        if (message) {
          that.msg.push(message);
        }
      });
    });
  }
  
  sendMessage(message: string) {
    this.stompClient.send('/app/send/message' , {}, message);
  }
}

SockJs.min.js and stomp.min.js are both declared in my index.html file.

When I'm testing this connection from my client angular, I get the following error : enter image description here

I don't have any error in api console, and I don't know why I'm getting this forbidden error.

Does anyone know why ? Thank you very much !

1

There are 1 answers

0
Jeremy On

setAllowedOrigins("*") may not work as expected with authentication.

You may need to add your origins explicitly. (for example ["http://localhost:4200"] )

Also, you may get more information by debugging the interceptors.

org.springframework.security.messaging.web.socket: DEBUG
org.springframework.web.socket.server: DEBUG

potential duplicate of Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]