【问题标题】:How to handle CORS origins with Stomp and SockJS in Spring 5.3 and newer?如何在 Spring 5.3 及更高版本中使用 Stomp 和 SockJS 处理 CORS 起源?
【发布时间】:2021-03-15 16:02:14
【问题描述】:

我正在开发一个同时使用 REST 端点和 SockJS websocket 的服务器应用程序。这曾经在 Spring 5.2 及更低版本下运行良好。

但是,从 5.3 版本开始org.springframework.web.cors.CorsConfiguration 中存在以下方法:

    public void validateAllowCredentials() {
        if (this.allowCredentials == Boolean.TRUE &&
                this.allowedOrigins != null && this.allowedOrigins.contains(ALL)) {

            throw new IllegalArgumentException(
                    "When allowCredentials is true, allowedOrigins cannot contain the special value \"*\"" +
                            "since that cannot be set on the \"Access-Control-Allow-Origin\" response header. " +
                            "To allow credentials to a set of origins, list them explicitly " +
                            "or consider using \"allowedOriginPatterns\" instead.");
        }
    }

到目前为止,我的套接字是这样配置的:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // prefix for the client to send messages to the server
        config.setApplicationDestinationPrefixes("/app");
        // prefix for the client to receive broadcasted messages from the server
        config.enableSimpleBroker("/topic");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // defines the url of the socket so the client can connect to it
        registry.addEndpoint("/socketendpoint").setAllowedOrigins("*").withSockJS();
    }
} 

现在我面临一个真正的问题:

  • 如果我将setAllowedOrigins("*") 保留在WebSocketConfiguration 中,那么我将面临validateAllowCredentials 中抛出的错误。
  • 如果我删除 setAllowedOrigins("*"),那么 SockJS 客户端将收到 Error during WebSocket handshake: Unexpected response code: 403

我在编译时不知道源域。

我已经尝试了一个 Cors 过滤器和一个 Cors 配置,它们使用典型的“将您在请求中找到的 origin 标头返回为 allow-origin”模式,该模式通常用于规避 allow-origin: "*",但一些 SockJS 请求没有分配origin 标头...

我该如何解决这个问题?

【问题讨论】:

  • 对于没有 Origin 请求标头的请求,不要在响应中发送 Access-Control-Allow-Origin 标头,因为无论这些请求来自哪里,它们re 不是来自将在响应中查找 Access-Control-Allow-Origin 标头的浏览器。唯一对 Access-Control-Allow-Origin 标头有任何用途的用户代理,甚至浏览器也只关心它只对浏览器本身添加了 Origin 标头的请求的响应。因此,任何缺少 Origin 标头的请求都不需要响应中的 Access-Control-Allow-Origin。
  • 你能找到解决办法吗?
  • 我们选择延迟依赖升级。 Spring 存储库最近已经提交了关于此问题的提交,它应该包含在即将发布的版本之一中;不知道它是否已经出来了。

标签: java spring websocket cors sockjs


【解决方案1】:

为了将来参考,随着最新的春季更新,现在有一个方法setAllowedOriginPatterns可以解决这个问题:

 registry.addEndpoint("/socketendpoint").setAllowedOriginPatterns("*").withSockJS();

【讨论】:

  • 对我来说,它修复了错误,但我不再收到其他 Spring 应用程序的任何消息。它发送一条消息,但没有收到任何消息。它适用于早期的 Spring Boot 版本(2.2 及更早版本)
  • 嗨,我正在尝试使用 corsfilter(在 spring security 中)和“setAllowedOriginPatterns("*")”(在 websocketconfig 中)访问“/websocket”端点。但是,通过同时保留它会给出“'Access-Control-Allow-Origin' 中的多个值”并从其中一个中删除,它会显示“没有 Access-Control-Allow-Origin 标头”或 403 错误。如何访问 websocket 端点?
【解决方案2】:

来自文档

配置允许的 Origin 标头值。这个检查主要是设计的 对于浏览器客户端。没有什么可以阻止其他类型的客户 修改 Origin 标头值。当启用 SockJS 和起源时 受到限制,不允许检查请求的传输类型 origin(基于 iframe 的传输)被禁用。因此,IE 6 当来源受到限制时,不支持到 9。 每个提供 允许的来源必须以“http://”、“https://”或“*”开头(表示 允许所有来源)。 默认情况下,只有相同来源的请求 被允许(空列表)。自从: 4.1.2 另见:RFC 6454: The Web Origin Concept , SockJS support transports by browser

你的代码

registry.addEndpoint("/socketendpoint").setAllowedOrigins("*").setAllowedOrigins().withSockJS();

应该是

 registry.addEndpoint("/socketendpoint").setAllowedOrigins("*").withSockJS();

【讨论】:

  • 对不起,原来的问题有错误;必须沿着复制粘贴的路线潜入代码 sn-p 并将其修剪回相关部分。现在已经修好了。
猜你喜欢
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
  • 2020-03-30
  • 1970-01-01
  • 2015-12-16
  • 2018-05-13
相关资源
最近更新 更多