弹簧的WebSocket消息代理添加额外的访问控制允许来源头respose

时间:2019-02-02 20:35:10

标签: spring-boot spring-websocket

我有一个包含Spring云网关的应用程序,该网关位于一个支持Web套接字连接(sockJS)的应用程序之前。网关转发到应用程序时会执行简单的URL重写。目前这两个正在运行弹簧引导2.0.5.RELEASE和Spring云Finchley.RELEASE。根据源I拉低,这应该使用弹簧的WebSockets-5.0.9。

当我尝试分别针对Spring-Boot和Spring-Cloud升级到2.1.2.RELEASE和Greenwich.RELEASE时,我的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;
    };
}

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

@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();
    }
}

如果我在.setAllowedOrigins("*")方法中注释掉registerStompEndpoints,则会正确地获得403访问被拒绝的响应,并且该响应仅具有网关注入的Access-Control-Allow-Origin标头。

使用此处显示的方法,websocket响应将按预期完成,并成功调用方,但响应标头包含网关 plus 注入的访问控制标头和另一个Access -Control-Allow-Origin标头,该标头设置为调用方的值(在本例中,前端应用程序为http://localhost:4200。)没有其他访问控制标头重复。

如何配置Spring websocket消息代理以不注入Access-Control-Allow-Origin标头?,此方法有效,但如果我回滚到2.0.5 / Finchley,则仍然可以使用。

1 个答案:

答案 0 :(得分:0)

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

  

此选项可用于为SockJS请求禁用自动添加CORS标头。

这是一个代码示例:

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {

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