Spring websocket 消息代理添加额外的 Access-Control-Allow-Origin header 来响应

Spring websocket message broker adding extra Access-Control-Allow-Origin header to respose

我有一个应用程序,其中包含一个 Spring 云网关,它位于一个应用程序前面,该应用程序(除其他外)支持网络套接字连接 (sockJS)。网关在转发到应用程序时会进行简单的 url 重写。两者目前是运行Spring-Boot2.0.5.RELEASE和Spring-CloudFinchley.RELEASE。根据我下拉的来源,这应该使用 spring-websockets-5.0.9.

当我尝试升级到 2.1.2.RELEASE 和 Greenwich.RELEASE 分别用于 Spring-Boot 和 Spring-Cloud 时,我的 websocket 连接开始失败,因为额外的 Access-Cloud-Allow-Origin 被注入到响应中。

我的网关有一个像这样的简单 CORS 过滤器(值是常量,不相关):

@Bean
public WebFilter corsFilter() {
    return (ServerWebExchange ctx, WebFilterChain chain) -> {
        Mono<Void> result;
        ServerHttpRequest request = ctx.getRequest();
        if (CorsUtils.isCorsRequest(request)) {
            ServerHttpResponse response = ctx.getResponse();
            HttpHeaders headers = response.getHeaders();
            headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
            headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
            headers.add("Access-Control-Max-Age", MAX_AGE);
            headers.add("Access-Control-Allow-Headers",ALLOWED_HEADERS);
            if (request.getMethod() == HttpMethod.OPTIONS) {
                response.setStatusCode(HttpStatus.OK);
                result = Mono.empty();
            } else {
                result = chain.filter(ctx);
            }
        } else {
            result = chain.filter(ctx);
        }
        return result;
    };
}

我在下游应用程序上的网络套接字配置就是这样:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOrigins("*")
            .withSockJS();
    }
}

如果我在 registerStompEndpoints 方法中注释掉 .setAllowedOrigins("*"),我会正确地得到 403 拒绝访问响应,并且响应只有 Access-Control-Allow-Origin header 作为注入通过网关。

使用此处显示的方法,websocket 响应按预期完成,并向调用方发出成功响应,但响应 header 包含网关注入的访问控制 header plus 另一个 Access-Control-Allow-Origin header 设置为调用者的值(在我的例子中,http://localhost:4200 用于 front-end 应用程序。 ) None 的其他访问控制 header 是重复的。

如何配置 Spring websocket 消息代理不注入 Access-Control-Allow-Origin header? 这是有效的,现在仍然有效如果我回滚到 2.0.5/Finchley。

我最近遇到了这个问题,我可以通过调用 setSupressCors 方法解决它。 documentation 表示

This option can be used to disable automatic addition of CORS headers for SockJS requests.

这是一个代码示例:

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket/handshake")
                .setAllowedOrigins("*")
                .withSockJS()
                .setSupressCors(true);
    }
}