Посредник сообщений websocket Spring добавляет дополнительный заголовок Access-Control-Allow-Origin для размещения - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть приложение, которое включает в себя облачный шлюз Spring, который находится перед приложением, которое (помимо прочего) поддерживает соединения с веб-сокетами (sockJS).Шлюз выполняет простую перезапись URL-адреса при пересылке в приложение.В настоящее время они работают под управлением Spring-Boot 2.0.5.RELEASE и Spring-Cloud Finchley.RELEASE.Согласно источнику, который я указал, это должно быть с использованием spring-websockets-5.0.9.

Когда я пытаюсь обновиться до 2.1.2.RELEASE и Greenwich.RELEASE для Spring-Boot и Spring-Cloud соответственномои подключения к веб-сокету начинают давать сбой, потому что в ответ добавляется дополнительная 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();
    }
}

Если я закомментирую .setAllowedOrigins("*") в методе registerStompEndpoints, я правильно получу 403 отказа в доступеответы, и ответ имеет только заголовок Access-Control-Allow-Origin, как введено шлюзом.

При использовании метода, показанного здесь, ответ веб-сокета завершается, как и ожидалось, с успешным ответом вызывающей стороне, но заголовок ответа содержит оба заголовка управления доступом, введенные шлюзом плюс другой заголовок Access-Control-Allow-Origin, для которого установлено значение вызывающей стороны (в моем случае http://localhost:4200 для внешнего приложения.) Ни один из других заголовков управления доступом не дублируется.

Как настроить брокер сообщений веб-сокетов Spring, чтобы он не вставлял заголовок Access-Control-Allow-Origin? Это работало и будет работать, если я вернусь к версии 2.0.5 / Finchley.

1 Ответ

0 голосов
/ 14 мая 2019

Я недавно столкнулся с этой проблемой и смог решить ее, вызвав метод setSupressCors.В документации говорится, что

Этот параметр можно использовать для отключения автоматического добавления заголовков CORS для запросов SockJS.

Вот пример кода:

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {

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