Springboot WebSocket: Cors policy blocking ws request - java

I'm trying to build a chat application. When hosting on a VPS I'm having this error message from browser
Access to XMLHttpRequest at 'http://localhost:8080/samplews/info?t=1603709911491' from origin 'http://my-server-ip:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is my WebSocketConfiguration class
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry){
registry.addEndpoint("/samplews").setAllowedOrigins("http://my-server-ip:8081").withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry){
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
I also tried to add a WebMvcConfiguration, which doesn't change anything:
#Configuration
#EnableWebMvc
public class WebAppConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://my-server-ip:8081")
.allowedMethods("GET");
}
I'm using springboot version 2.2.1.RELEASE and also tried with the latest release.
The client is an angular application which does nothing but this:
ngOnInit() {
const ws = new SockJS(this.webSocketEndPoint);
this.stompClient = Stomp.over(ws);
this.stompClient.connect({}, (frame) => {
// TODO: Do something when connecting ws
console.log(frame);
});
}
Client and server are on two different docker containers, this is docker ps result:
f3aa46625fc4 chatapp "java -jar /app.jar" 15 minutes ago Up 15 minutes 0.0.0.0:8080->8080/tcp chatapp
7aa6e8a885de chatui "catalina.sh run" 16 minutes ago Up 16 minutes 0.0.0.0:8081->8080/tcp chatui
It all works fine locally (even if I use docker or ng serve the client and start the springboot server app via IntelliJ)
I don't think I'm missing basic information, any ideas?
edit:
I've changed this
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer
to this:
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer
And now I'm getting this error:
GET http://localhost:8080/samplews/info?t=1603798741148 net::ERR_CONNECTION_REFUSED
edit:
I was using localhost as the URL target for opening the socket, I should use the server ip instead, solved

Related

Blocked Cross Origin Spring Boot And React

I am working on a project in react and spring boot, and I got issue with the cross origin from my spring server, I put the crossOrogin annotation on my controller and is not working me I tried many ways (from spring official web) non of them worked to me. Is anyone can help me please with that I really don’t know what to do. Here is my controller , ;
},
And this is my error with react:
error image for react uskg chrome
try this way:
#Configuration
public class CrossConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*") // SpringBoot2.4.0 [allowedOriginPatterns]replace[allowedOrigins]
.allowedMethods("*")
.maxAge(3600)
.allowCredentials(true);
}
}

How can i make my springboot app websocket app get connected via a "ws://" url while using stomp

I have a springboot app and i want to make the websocket connect via devices like phone so i am looking for a way to make my websocket have an entry point that starts with "ws://". When testing my default websocket url which is supposed to be "ws://localhost:8080/websocket-example" on "http://www.websocket.org/echo.html" it does not go through. but the sockjs calls it in my client side using ("http://localhost:8080/websocket-example") which works :
var socket = new SockJS('http://localhost:8080/websocket-example');
stompClient = Stomp.over(socket);
stompClient.connect({},function (frame) {
}
I am presently using stomp on it and my configuration looks like this:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/websocket-example")
.setHandshakeHandler(new CustomHandshakeHandler()).setAllowedOrigins("*")
.withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
according to this post it said i could achieve a ws:// entrypoint by removing .withSockJS() which i did, but it still didnt work (on further reading, it was stated that this doesnt work on springboot). The other option was to remove stomp totally, this option works, but then i wouldn't be able to route messages directly to individuals users.
How can i create a ws:// entry point while maintaining stomp on my server side ?
I had a similar problem. Try this, should help.
var socket = new WebSocket('ws://localhost:8080/websocket-example/websocket');

simpMessagingTemplate doesn't send message from client to server

I want to exchange messages by web sockets between 2 java apps.
I have the following server configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/queue", "/topic");
registry.setUserDestinationPrefix("/user");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//todo remove handshake handler when authorization is implemented
registry.addEndpoint("/ws").setAllowedOrigins("*").setHandshakeHandler(new TestHandshakeHandler()).withSockJS();
}
}
and inside class marked with #Controller I have wrote following theme:
#MessageMapping("/consumer/client/add")
public void addClientRequest(String msgReq) {
logger.info(msgReq);
}
and inside clien I do connect and in sime bean I wrote following:
#Autowired
private SimpMessagingTemplate simpMessagingTemplate;
...
simpMessagingTemplate.convertAndSend("/app/consumer/client/add", new StubObject("message"));
But after sending from client method addClientRequest doesn't invoke.
Please advice ways to troubleshot this issue.
Actually I don't understand issue. Maybe I send to wrong destination or I have issue with configuration or path is wrong or something else.
P.S.
I know that I can extend StompSessionHandlerAdapter
and obtain session from there but looks like it is the bad style and should be another way to achieve it
P.S.2
Inside class WebSocketTcpConnectionHandlerAdapter(inner class inside WebSocketStompClient) I see private volatile WebSocketSession session;
I want to obtain this object to send messages
I don't think it was designed to be used like this.
I think you must use a specific websocket client. This one for exemple :
http://www.programmingforliving.com/2013/08/jsr-356-java-api-for-websocket-client-api.html
This code :
#MessageMapping("/consumer/client/add")
public void addClientRequest(String msgReq) {
logger.info(msgReq);
}
Will NOT connect to a websocket client and wait to have messages. It expect a client to connect throught it and send messages.

Error during WebSocket handshake: Unexpected response code: 403

I have implemented WebSockets with Spring Boot Application and have the below error message when trying to test the ws connection with the chrome extension 'Smart websocket client'.
However, I have no problem when run the Spring Boot Application locally.
WebSocket connection to 'ws://192.168.X.XYZ:8080/test' failed:
Error during WebSocket handshake: Unexpected response code: 403
The only difference which I see is in the Request headers:
In the one it works - Origin:http://192.168.X.XYZ:8080
In the one it does not work - Origin:chrome-extension://omalebghpgejjiaoknljcfmglgbpocdp
What I did in the WebSocketConfig class is below:
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(), "/test").setAllowedOrigins("http://192.168.X.XYZ:8080");
}
and still does not work.
Could you please advise what the reason for that error might be and how to fix it?
Thank you in advance.
You need to configure your "chrome-extension://..." origin as an allowed origin or even "*", otherwise it's rejected by the server.
On update to spring boot 2.4, it also requires:
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
};
}
and #EnableAutoConfiguration on the config class.

Spring websockets, NettyTcpClient - Failed to connect

I'm receiving the following message every 5 seconds:
[WEBAPP] 02 Nov 2014 17:55:43 INFO NettyTcpClient - Failed to connect to /127.0.0.1:61613. Attempting reconnect in 5000ms.
I'm using spring 4 with stomp and activemq
any ideas why that happnes?
BTW: the webapp runs on tomcat #1 while my activemq broker is located # a different machine.
Ok the URL was wrong.
I fixed it with the following code:
config.enableStompBrokerRelay("/topic","/queue/").setRelayHost(THE_RIGHT_URL);
I slved this problem with this configuration:
#Configuration
#EnableConfigurationProperties(ActiveMQProperties.class)
public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {
#Autowired
private ActiveMQProperties activeMQProperties;
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableStompBrokerRelay("/notify").setRelayHost("192.168.99.100")
.setSystemLogin("admin").setSystemPasscode("admin");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/createBookJob").withSockJS();
}
}
In the my use case I'm experiencing whe use activeMq as STOMP provider ina docker image.
setRelayHost("192.168.99.100") was usefull becouse 192.168.99.100 is the defualt ip that I use
.setClientLogin("admin").setClientPasscode("admin")
.setSystemLogin("admin").setSystemPasscode("admin");
becouse in active mq the default users has admin admin as user and password
it works for me
I hope that this can help you

Categories