diff options
| author | Robert Godfrey <rgodfrey@apache.org> | 2014-01-13 17:32:17 +0000 |
|---|---|---|
| committer | Robert Godfrey <rgodfrey@apache.org> | 2014-01-13 17:32:17 +0000 |
| commit | 93dbec4289155847feb3f63ea24623d824ac73df (patch) | |
| tree | c100021e95debca0c67a182f9cd56d96ce6049f2 /qpid/java | |
| parent | 1721fffb6ccb148bac35c1353ea17bf2937be2a9 (diff) | |
| download | qpid-python-93dbec4289155847feb3f63ea24623d824ac73df.tar.gz | |
QPID-5459 : [Java Broker] add secure websocket support to the broker, including ssl client auth
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1557782 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
4 files changed, 38 insertions, 8 deletions
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java index 5aab3db81a..c255ce2f4a 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java @@ -82,7 +82,7 @@ public class AmqpPortAdapter extends PortAdapter } SSLContext sslContext = null; - if (transports.contains(Transport.SSL)) + if (transports.contains(Transport.SSL) || transports.contains(Transport.WSS)) { sslContext = createSslContext(); } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java index 8dc446e5b2..25a8cc93ad 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java @@ -111,7 +111,7 @@ public class PortFactory throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but has no trust stores configured."); } - if(useClientAuth && !port.getTransports().contains(Transport.SSL)) + if(useClientAuth && !(port.getTransports().contains(Transport.SSL) || port.getTransports().contains(Transport.WSS))) { throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but doesn't use SSL transport."); } diff --git a/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java index 095ac993ae..4a104a830c 100644 --- a/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java +++ b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java @@ -34,6 +34,7 @@ import org.apache.qpid.transport.network.NetworkConnection; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; import org.eclipse.jetty.server.ssl.SslSocketConnector; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.websocket.WebSocket; @@ -46,6 +47,9 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.security.Principal; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collections; import java.util.Set; class WebSocketProvider implements AcceptingTransport @@ -97,7 +101,8 @@ class WebSocketProvider implements AcceptingTransport { SslContextFactory factory = new SslContextFactory(); factory.setSslContext(_sslContext); - connector = new SslSocketConnector(factory); + factory.setNeedClientAuth(true); + connector = new SslSelectChannelConnector(factory); } else { @@ -116,9 +121,21 @@ class WebSocketProvider implements AcceptingTransport @Override public WebSocket doWebSocketConnect(final HttpServletRequest request, final String protocol) { + + Principal principal = null; + if(Collections.list(request.getAttributeNames()).contains("javax.servlet.request.X509Certificate")) + { + X509Certificate[] certificates = + (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); + if(certificates != null && certificates.length != 0) + { + principal = certificates[0].getSubjectDN(); + } + } + SocketAddress remoteAddress = new InetSocketAddress(request.getRemoteHost(), request.getRemotePort()); SocketAddress localAddress = new InetSocketAddress(request.getLocalName(), request.getLocalPort()); - return AMQP_WEBSOCKET_SUBPROTOCOL.equals(protocol) ? new AmqpWebSocket(_transport, localAddress, remoteAddress) : null; + return AMQP_WEBSOCKET_SUBPROTOCOL.equals(protocol) ? new AmqpWebSocket(_transport, localAddress, remoteAddress, principal) : null; } }; @@ -144,17 +161,20 @@ class WebSocketProvider implements AcceptingTransport { private final SocketAddress _localAddress; private final SocketAddress _remoteAddress; + private final Principal _userPrincipal; private Connection _connection; private final Transport _transport; private ProtocolEngine _engine; private AmqpWebSocket(final Transport transport, final SocketAddress localAddress, - final SocketAddress remoteAddress) + final SocketAddress remoteAddress, + final Principal userPrincipal) { _transport = transport; _localAddress = localAddress; _remoteAddress = remoteAddress; + _userPrincipal = userPrincipal; } @Override @@ -170,7 +190,9 @@ class WebSocketProvider implements AcceptingTransport _engine = _factory.newProtocolEngine(); - final NetworkConnection connectionWrapper = new ConnectionWrapper(connection, _localAddress, _remoteAddress); + final ConnectionWrapper connectionWrapper = + new ConnectionWrapper(connection, _localAddress, _remoteAddress); + connectionWrapper.setPeerPrincipal(_userPrincipal); _engine.setNetworkConnection(connectionWrapper, connectionWrapper.getSender()); } @@ -190,6 +212,7 @@ class WebSocketProvider implements AcceptingTransport private Principal _principal; private int _maxWriteIdle; private int _maxReadIdle; + private Principal _peerPrincipal; public ConnectionWrapper(final WebSocket.Connection connection, final SocketAddress localAddress, @@ -270,7 +293,6 @@ class WebSocketProvider implements AcceptingTransport @Override public Principal getPeerPrincipal() { - //TODO: how do we populate this? return _principal; } @@ -285,5 +307,10 @@ class WebSocketProvider implements AcceptingTransport { return _maxWriteIdle; } + + void setPeerPrincipal(final Principal peerPrincipal) + { + _peerPrincipal = peerPrincipal; + } } } diff --git a/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java index 662f16ce5b..e7c5a786b5 100644 --- a/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java +++ b/qpid/java/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketTransportProviderFactory.java @@ -24,8 +24,10 @@ import org.apache.qpid.server.model.Transport; import org.apache.qpid.server.plugin.TransportProviderFactory; import org.apache.qpid.server.transport.TransportProvider; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.HashSet; import java.util.Set; public class WebSocketTransportProviderFactory implements TransportProviderFactory @@ -36,7 +38,8 @@ public class WebSocketTransportProviderFactory implements TransportProviderFacto @Override public Set<Set<Transport>> getSupportedTransports() { - return Collections.singleton((Set<Transport>)EnumSet.of(Transport.WS)); + return new HashSet<Set<Transport>>(Arrays.asList(EnumSet.of(Transport.WS), + EnumSet.of(Transport.WSS))); } @Override |
