代码之家  ›  专栏  ›  技术社区  ›  Roddy of the Frozen Peas

添加额外访问控制的springwebsocket消息代理允许源标头响应

  •  0
  • Roddy of the Frozen Peas  · 技术社区  · 6 年前

    我有一个应用程序,它包括一个springcloudgateway,它位于一个支持websocketconnections(sockJS)的应用程序前面。网关在转发到应用程序时进行简单的url重写。这两个版本目前运行的是springboot2.0.5.RELEASE和springcloudFinchley.释放. 根据我找到的源代码,这应该使用spring-websockets-5.0.9。

    当我尝试升级到2.1.2.RELEASE和格林威治发布对于springboot和springcloud,我的websocket连接开始失败,因为一个额外的accesscloudalloworigin被注入到响应中。

    @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 denied响应,并且该响应只有由网关注入的access Control Allow Origin头。

    使用如这里所示的方法,websocket响应按预期完成,并向调用方成功响应,但响应头包含网关注入的访问控制头 另一个访问控制Allow Origin头,它被设置为调用者的值(在我的例子中, http://localhost:4200 对于前端应用程序。)其他访问控制标头都不重复。

    这是有效的,如果我回到2.0.5/Finchley,它仍然有效。

    0 回复  |  直到 6 年前
        1
  •  1
  •   Dag Fort    6 年前

    我最近遇到了这个问题,我打电话解决了 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);
        }
    }