【问题标题】:Websocket in Spring Boot app - Getting 403 ForbiddenSpring Boot 应用程序中的 Websocket - 获取 403 Forbidden
【发布时间】:2015-12-28 17:32:35
【问题描述】:

Spring Boot 应用程序中的 Websocket - 得到 403 禁止

当我在 Eclipse 中运行它时,我可以使用 sockjs/stompjs 从客户端连接到 websocket(没有 spring boot)。

但是当我为 websocket 代码创建一个 Spring boot jar(gradlew build) 并运行 java -jar websocket-code.jar 时,连接到 websocket 时出现 403 错误。

我没有对 websockets 的身份验证。 我有一个 CORS 过滤器,并认为所有标题都在请求/响应中。

下面是我的 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'
}

更新:

添加了一个 CORS 过滤器 response.setHeader("Access-Control-Allow-Origin", "http://localhost:8089");

在客户端的萤火虫中

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

我请求的来源在允许来源列表中。日志中仍然收到 Request Rejected 消息。

【问题讨论】:

    标签: java gradle websocket spring-boot sockjs


    【解决方案1】:

    我遇到了类似的问题,并通过将允许的来源设置为“*”在 WebSocketConfig 中修复了它。

    @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
    }
    

    【讨论】:

    • 感谢您的回答。我认为 setAllowedOrigins 已在新版本中添加到 StompWebSocketEndpointRegistration 中。我认为您的解决方案应该适用于新版本。我使用的是较旧的 websocket jar。
    • 对 allowedOrigins 使用这样的通配符不是不安全吗?
    • 谢谢,我最初的想法是在我的 WebMvcConfigurerAdapter 中为 CORS 设置允许的来源。不过这行得通!
    • @niilzon,这取决于操作目的。一般来说,我宁愿同意你的看法。但是您可以简单地与特定主机交换通配符,例如setAllowedOrigins("http://somehost")。这可能看起来很清楚,但当我偶然发现这篇文章时,我有一种表达的冲动:-)
    • 请注意,这也适用于在WebSocketConfigurer 中注册的原始 Web 套接字。在方法public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {} 中,您可以调用registry.addHandler(new MyWebSocketHandler(), "/some-path").setAllowedOrigins("*");。不幸的是,WebSocket 无法告诉您这是一个 CORS 问题……403 非常具有误导性。
    【解决方案2】:

    尝试添加

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

    我猜“你的端点”是由@SendTo 在控制器中注册的

    【讨论】:

      【解决方案3】:

      我的 2 个环境之间的区别在于 jar 的版本。

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

      由于 spring-boot-starter-websocket 在打包时的依赖关系,尽管 spring_version 为 spring_version=4.0.6.RELEASE,但它仍在获取 spring-websocket-4.1.7.RELEASE。

      修改了 build.gradle 中解决问题的依赖项。

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

      我认为在最新版本的 spring-websocket jar 中,StompWebSocketEndpointRegistration 类具有必须使用的 setAllowedOrigins 方法。没有尝试过。

      但是 CORS 使用

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

      正在使用旧版本。

      【讨论】:

      • 不确定这些是否仍然有效。对我来说,它说 Web 套接字层需要凭据是真实的,即使我将我的设置放在 CORS 中也是如此。我仍然得到 403 禁止
      • 在 spring boot mvn 中,我只是更新了相同的版本并且它工作了:stackextend.com/angular/websocket-with-spring-boot-and-angular ver: 2.0.7.RELEASE
      【解决方案4】:

      作为参考,较新版本的 spring 需要不同的方法:

      registry.addEndpoint("/websocket-connection").setAllowedOriginPatterns("*").withSockJS();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-26
        • 1970-01-01
        • 2016-10-20
        • 2017-09-21
        • 2019-02-20
        • 2016-03-11
        • 2019-04-02
        • 1970-01-01
        相关资源
        最近更新 更多