INT-4039: Add Allowed Origins to WebSockets

JIRA: https://jira.spring.io/browse/INT-4039

Also add `suppressCors` for the `SockJsServiceOptions`

Polishing according PR comments
This commit is contained in:
Artem Bilan
2016-05-25 18:55:59 -04:00
committed by Gary Russell
parent d414383eac
commit f5488efcaa
8 changed files with 168 additions and 83 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,6 +58,8 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
private SockJsServiceOptions sockJsServiceOptions;
private String[] origins;
public ServerWebSocketContainer(String... paths) {
this.paths = paths;
}
@@ -91,6 +93,18 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
return this;
}
/**
* Configure allowed {@code Origin} header values.
* @param origins the origins to allow.
* @return the current ServerWebSocketContainer
* @since 4.3
* @see WebSocketHandlerRegistration#setAllowedOrigins(String...)
*/
public ServerWebSocketContainer setAllowedOrigins(String... origins) {
this.origins = origins; //NOSONAR - fully delegated
return this;
}
public ServerWebSocketContainer withSockJs(SockJsServiceOptions... sockJsServiceOptions) {
if (ObjectUtils.isEmpty(sockJsServiceOptions)) {
this.sockJsServiceOptions = new SockJsServiceOptions();
@@ -118,7 +132,8 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
WebSocketHandlerRegistration registration = registry.addHandler(webSocketHandler, this.paths)
.setHandshakeHandler(this.handshakeHandler)
.addInterceptors(this.interceptors);
.addInterceptors(this.interceptors)
.setAllowedOrigins(this.origins);
if (this.sockJsServiceOptions != null) {
SockJsServiceRegistration sockJsServiceRegistration = registration.withSockJS();
@@ -155,6 +170,10 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
if (this.sockJsServiceOptions.messageCodec != null) {
sockJsServiceRegistration.setMessageCodec(this.sockJsServiceOptions.messageCodec);
}
if (this.sockJsServiceOptions.suppressCors != null) {
sockJsServiceRegistration.setSupressCors(this.sockJsServiceOptions.suppressCors);
}
}
}
@@ -184,6 +203,8 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
private SockJsMessageCodec messageCodec;
private Boolean suppressCors;
public SockJsServiceOptions setTaskScheduler(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
return this;
@@ -234,6 +255,11 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
return this;
}
public SockJsServiceOptions setSuppressCors(boolean suppressCors) {
this.suppressCors = suppressCors;
return this;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -87,6 +87,7 @@ public class ServerWebSocketContainerParser extends AbstractSingleBeanDefinition
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(sockjsBuilder, sockjs, "scheduler",
"taskScheduler");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(sockjsBuilder, sockjs, "message-codec");
IntegrationNamespaceUtils.setValueIfAttributeDefined(sockjsBuilder, sockjs, "suppress-cors");
String transportHandlers = sockjs.getAttribute("transport-handlers");
if (StringUtils.hasText(transportHandlers)) {
@@ -103,6 +104,7 @@ public class ServerWebSocketContainerParser extends AbstractSingleBeanDefinition
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "handshake-handler");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "send-buffer-size-limit");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "send-time-limit");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "allowed-origins");
}
}

View File

@@ -248,6 +248,15 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="suppress-cors" type="xsd:string" default="false">
<xsd:annotation>
<xsd:documentation>
This option can be used to disable automatic addition
of CORS headers for SockJS requests.
The default value is 'false'.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
@@ -311,6 +320,24 @@
<xsd:union memberTypes="xsd:int xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="allowed-origins" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Configure allowed Origin header values. Multiple origins may be specified
as a comma-separated list.
This check is mostly designed for browser clients. There is noting preventing other
types of client to modify the Origin header value.
When SockJS is enabled and allowed origins are restricted, transport types that do not
use Origin headers for cross origin requests (jsonp-polling, iframe-xhr-polling,
iframe-eventsource and iframe-htmlfile) are disabled. As a consequence, IE6/IE7 are not
supported and IE8/IE9 will only be supported without cookies.
By default, all origins are allowed.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>