35

Websocket in Spring Boot app - Getting 403 Forbidden

I can connect to the websocket from client using sockjs/stompjs when I run this in eclipse (no spring boot).

But when I create a Spring boot jar(gradlew build) for the websocket code and run the java -jar websocket-code.jar I get a 403 error connecting to the websocket.

I have no authentication for the websockets. I have a CORS filters and think have all headers right in request/response.

Below is my build.gradle

apply plugin: 'java'
apply plugin: 'spring-boot'
apply plugin: 'war'

sourceCompatibility = 1.7
version = '1.0'

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
    }
}

configurations {
    compile.exclude module: "spring-boot-starter-tomcat"
}

dependencies {
    compile "org.springframework:spring-web:$spring_version"
    compile "org.springframework:spring-webmvc:$spring_version"
    compile "org.springframework:spring-websocket:$spring_version"
    compile "org.springframework:spring-messaging:$spring_version"
    compile "org.springframework.boot:spring-boot-starter-websocket"
    compile "org.springframework.boot:spring-boot-starter-web"
    compile "com.fasterxml.jackson.core:jackson-databind:2.6.2"
    compile "com.fasterxml.jackson.core:jackson-core:2.6.2"
    compile "com.fasterxml.jackson.core:jackson-annotations:2.6.2"
    compile "org.springframework.amqp:spring-rabbit:1.3.5.RELEASE"
    compile("org.springframework:spring-tx")
    compile("org.springframework.boot:spring-boot-starter-web:1.2.6.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-jetty:1.2.6.RELEASE")
    testCompile group: 'junit', name: 'junit', version: '4.11'
    testCompile "org.springframework:spring-test:$spring_version"
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.5'
}

Update:

Added a CORS filter with response.setHeader("Access-Control-Allow-Origin", "http://localhost:8089");

In firebug on Client side

Request Headers 
Origin  
http://localhost:8089

Response Headers
Access-Control-Allow-Origin
http://localhost:8089

Server Logs
2015-10-02 16:57:31.372 DEBUG 1848 --- [qtp374030679-14] o.s.w.s.s.t.h.DefaultSockJsService       : Request rejected, Origin header value http://localhost:8089 not allowed

Origin I am requesting from is in the Allow-origin list. Still getting Request Rejected message in the logs.

user3755282
  • 813
  • 2
  • 9
  • 15

4 Answers4

92

I had a similar issue and fixed it in the WebSocketConfig by setting the allowed origins to "*".

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // the endpoint for websocket connections
        registry.addEndpoint("/stomp").setAllowedOrigins("*").withSockJS();
    }

    // remaining config not shown as not relevant
}
Dustin Shimono
  • 1,031
  • 7
  • 10
  • 2
    Thanks for the answer. I think setAllowedOrigins has been added to StompWebSocketEndpointRegistration in new release. I think your solution should work in new release. I am using as older websocket jar. – user3755282 Oct 08 '15 at 00:11
  • 9
    isn't it insecure to use such a wildcard for allowedOrigins ? – niilzon Oct 08 '16 at 12:59
  • Thank you, my initial idea was to set the allowed origins in my WebMvcConfigurerAdapter for CORS. This worked though! – Ryan Pelletier Nov 09 '16 at 13:59
  • 1
    @niilzon, that depends on the operation purpose. Generally speaking I would rather agree with you. But you can simply exchange the wildcard with specific hosts like `setAllowedOrigins("http://somehost")`. That might seem pretty clear but I felt the urge to state it when stumbling on this post :-) – Fencer Nov 30 '17 at 14:46
  • where can we locate this file? – Bilal Ahmed Yaseen Dec 28 '17 at 11:38
  • 4
    Note that this works as well for raw web sockets registered in `WebSocketConfigurer`. In method `public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {}` you can call `registry.addHandler(new MyWebSocketHandler(), "/some-path").setAllowedOrigins("*");`. It's unfortunate that WebSocket is not able to tell you that it's a CORS problem... 403 is quite misleading. – user5365075 Feb 21 '18 at 08:44
5

try to add

registry.addEndpoint("/your-end-point").setAllowedOrigins("*").withSockJS();

"your-end-point" is registered by @SendTo in controller I guess

Long Do Thanh
  • 336
  • 4
  • 4
4

Difference between my 2 environment was the version of jars.

spring-boot-starter-websocket-1.2.5.RELEASE.jar
spring-websocket-4.1.7.RELEASE.jar

Because of the spring-boot-starter-websocket dependency while packaging it was picking up spring-websocket-4.1.7.RELEASE inspite of the spring_version being spring_version=4.0.6.RELEASE.

Modified the dependency in build.gradle that fixed the problem.

compile "org.springframework.boot:spring-boot-starter-websocket:1.1.0.RELEASE"

I think in latest version of spring-websocket jar the class StompWebSocketEndpointRegistration has setAllowedOrigins method that has to be used.Have not tried this.

But CORS filter with

response.setHeader("Access-Control-Allow-Origin", "http://localhost:8089");

is working with older version.

user3755282
  • 813
  • 2
  • 9
  • 15
  • Not sure if these still works anymore. For me its saying the web socket layer requires credentials to be true and even when i put my set my allow origins in the CORS. I still get a 403 forbidden – numerical25 Dec 02 '15 at 14:28
  • in spring boot mvn, I just update same version and it worked: https://www.stackextend.com/angular/websocket-with-spring-boot-and-angular/ ver: 2.0.7.RELEASE – nobjta_9x_tq Dec 10 '19 at 08:09
3

For reference, newer versions of spring require a different method:

registry.addEndpoint("/websocket-connection").setAllowedOriginPatterns("*").withSockJS();
Galen Howlett
  • 530
  • 4
  • 12