9

I am using Spring Boot 1.3.0.RELEASE. My code is based on the Starting Guide for websocket in Spring Boot using Stomp and SocketJS.

When I run the Client from localhost:8080 (Spring Server)... Of course it works. Its not until I try to call it from a Different Port, that I get a 403 Forbidden. My CorsFilter is set below.

Getting Started Web Sockets With Spring Boot

My Client is ....http://localhost:3000

My Spring Boot Server is ... http://localhost:8080

I setup my CorsFilter to access my client...

CorsFilter

package hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CorsFilter implements Filter {

    private final Logger log = LoggerFactory.getLogger(CorsFilter.class);

    public CorsFilter() {
        log.info("SimpleCORSFilter init");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String clientOrigin = request.getHeader("origin");
        response.addHeader("Access-Control-Allow-Origin", clientOrigin);
        response.setHeader("Access-Control-Allow-Methods", "POST, GET,  DELETE, PUT");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, Accept, X-Requested-With, Content-Type, " +
                        "Access-Control-Request-Method, Access-Control-Request-Headers");

        if (request.getMethod().equals("OPTIONS")) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

}

Request Headers

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36

Response Headers

Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:POST, GET,  DELETE, PUT
Access-Control-Allow-Origin:http://localhost:3000
Access-Control-Max-Age:3600
Cache-Control:no-store, no-cache, must-revalidate, max-age=0
Content-Length:0
Date:Wed, 02 Dec 2015 13:59:25 GMT
Server:Apache-Coyote/1.1
numerical25
  • 10,524
  • 36
  • 130
  • 209
  • maybe you are missing `response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");` ? – abinsalm Dec 02 '15 at 16:20
  • I will give it a try – numerical25 Dec 02 '15 at 17:40
  • nope, I updated what I added. – numerical25 Dec 02 '15 at 17:46
  • 1
    Try adding this in your WebSocket configuration class (AbstractWebSocketMessageBrokerConfigurer) in method `registerStompEndpoints` add `setAllowedOrigins("*")`. For example `registry.addEndpoint("/chat").setAllowedOrigins("*").withSockJS();` – Bojan Trajkovski Dec 07 '15 at 12:57

1 Answers1

25

Adding an answer in case anyone else comes across this question. As suggested in the comments, you need to use the setAllowedOrigins method as described in the docs. So assuming that this is the tutorial you are following, you would end up with a configuration class that looks like this:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

  @Override
  public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/your/topic");
    config.setApplicationDestinationPrefixes("/yourapp");
  }

  @Override
  public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/your/endpoint").setAllowedOrigins("http://localhost:3000").withSockJS();
  }

}

That would allow a stomp client running on localhost:3000 to subscribe to the /your/endpoint.

Mr. Spice
  • 1,552
  • 1
  • 15
  • 15
  • Spice can i use separate ports for websocket and http in spring boot – naila naseem Apr 06 '18 at 11:06
  • @naila Configuring your spring boot application to listen to multiple ports is discussed here - https://stackoverflow.com/questions/36357135/configure-spring-boot-with-two-ports – Mr. Spice Apr 17 '18 at 11:12
  • This only works for localhost, I always get CORS error when I call websocket hosted on a server such as `https://example.com/my-rest-app/websocket` – Francisco Souza Aug 05 '21 at 11:51