如何在 Spring 5.3 及更高版本中使用 Stomp 和 SockJS 处理 CORS 源?

How to handle CORS origins with Stomp and SockJS in Spring 5.3 and newer?

我正在开发一个同时使用 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();
    }
} 

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

我在编译时不知道源域。

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

我该如何解决这个问题?

来自文档

Configure allowed Origin header values. This check is mostly designed for browser clients. There is nothing preventing other types of client to modify the Origin header value. When SockJS is enabled and origins are restricted, transport types that do not allow to check request origin (Iframe based transports) are disabled. As a consequence, IE 6 to 9 are not supported when origins are restricted. Each provided allowed origin must start by "http://", "https://" or be "*" (means that all origins are allowed). By default, only same origin requests are allowed (empty list). Since: 4.1.2 See Also: RFC 6454: The Web Origin Concept , SockJS supported transports by browser

您的代码

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

应该是

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

为了将来参考,根据最新的 spring 更新,现在有一种方法 setAllowedOriginPatterns 可以解决此问题:

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