ARTEMIS-594 support HTTPS access to hawtio
This commit is contained in:
parent
b88969cd7d
commit
23475caca9
|
@ -72,6 +72,7 @@ public class Create extends InputAbstract {
|
|||
public static final String ETC_LOGGING_PROPERTIES = "etc/logging.properties";
|
||||
public static final String ETC_BOOTSTRAP_XML = "etc/bootstrap.xml";
|
||||
public static final String ETC_BROKER_XML = "etc/broker.xml";
|
||||
public static final String ETC_WEB_KEYSTORE = "etc/keystore.jks";
|
||||
|
||||
public static final String ETC_ARTEMIS_ROLES_PROPERTIES = "etc/artemis-roles.properties";
|
||||
public static final String ETC_ARTEMIS_USERS_PROPERTIES = "etc/artemis-users.properties";
|
||||
|
@ -624,6 +625,9 @@ public class Create extends InputAbstract {
|
|||
filters.put("${bootstrap-web-settings}", applyFilters(readTextFile(ETC_BOOTSTRAP_WEB_SETTINGS_TXT), filters));
|
||||
}
|
||||
|
||||
//keystore
|
||||
write(ETC_WEB_KEYSTORE);
|
||||
|
||||
if (noAmqpAcceptor) {
|
||||
filters.put("${amqp-acceptor}", "");
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -33,6 +33,21 @@ public class WebServerDTO extends ComponentDTO {
|
|||
@XmlAttribute(required = true)
|
||||
public String path;
|
||||
|
||||
@XmlAttribute
|
||||
public Boolean clientAuth;
|
||||
|
||||
@XmlAttribute
|
||||
public String keyStorePath;
|
||||
|
||||
@XmlAttribute
|
||||
public String keyStorePassword;
|
||||
|
||||
@XmlAttribute
|
||||
public String trustStorePath;
|
||||
|
||||
@XmlAttribute
|
||||
public String trustStorePassword;
|
||||
|
||||
@XmlElementRef
|
||||
public List<AppDTO> apps;
|
||||
|
||||
|
|
|
@ -22,11 +22,16 @@ import org.apache.activemq.artemis.dto.AppDTO;
|
|||
import org.apache.activemq.artemis.dto.ComponentDTO;
|
||||
import org.apache.activemq.artemis.dto.WebServerDTO;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.SecureRequestCustomizer;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.SslConnectionFactory;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -47,7 +52,33 @@ public class WebServerComponent implements ExternalComponent {
|
|||
webServerConfig = (WebServerDTO) config;
|
||||
uri = new URI(webServerConfig.bind);
|
||||
server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
String scheme = uri.getScheme();
|
||||
ServerConnector connector = null;
|
||||
|
||||
if ("https".equals(scheme)) {
|
||||
SslContextFactory sslFactory = new SslContextFactory();
|
||||
sslFactory.setKeyStorePath(webServerConfig.keyStorePath == null ? artemisInstance + "/etc/keystore.jks" : webServerConfig.keyStorePath);
|
||||
sslFactory.setKeyStorePassword(webServerConfig.keyStorePassword == null ? "password" : webServerConfig.keyStorePassword);
|
||||
if (webServerConfig.clientAuth != null) {
|
||||
sslFactory.setNeedClientAuth(webServerConfig.clientAuth);
|
||||
if (webServerConfig.clientAuth) {
|
||||
sslFactory.setTrustStorePath(webServerConfig.trustStorePath);
|
||||
sslFactory.setTrustStorePassword(webServerConfig.trustStorePassword);
|
||||
}
|
||||
}
|
||||
|
||||
SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(sslFactory, "HTTP/1.1");
|
||||
|
||||
HttpConfiguration https = new HttpConfiguration();
|
||||
https.addCustomizer(new SecureRequestCustomizer());
|
||||
HttpConnectionFactory httpFactory = new HttpConnectionFactory(https);
|
||||
|
||||
connector = new ServerConnector(server, sslConnectionFactory, httpFactory);
|
||||
|
||||
}
|
||||
else {
|
||||
connector = new ServerConnector(server);
|
||||
}
|
||||
connector.setPort(uri.getPort());
|
||||
connector.setHost(uri.getHost());
|
||||
|
||||
|
|
|
@ -37,16 +37,22 @@ import io.netty.handler.codec.http.HttpMethod;
|
|||
import io.netty.handler.codec.http.HttpObject;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import org.apache.activemq.artemis.component.WebServerComponent;
|
||||
import org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport;
|
||||
import org.apache.activemq.artemis.dto.WebServerDTO;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
|
||||
public class WebServerComponentTest extends Assert {
|
||||
|
||||
static final String URL = System.getProperty("url", "http://localhost:8161/WebServerComponentTest.txt");
|
||||
static final String SECURE_URL = System.getProperty("url", "https://localhost:8448/WebServerComponentTest.txt");
|
||||
private Bootstrap bootstrap;
|
||||
private EventLoopGroup group;
|
||||
|
||||
|
@ -94,6 +100,119 @@ public class WebServerComponentTest extends Assert {
|
|||
Assert.assertFalse(webServerComponent.isStarted());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleSecureServer() throws Exception {
|
||||
WebServerDTO webServerDTO = new WebServerDTO();
|
||||
webServerDTO.bind = "https://localhost:8448";
|
||||
webServerDTO.path = "webapps";
|
||||
webServerDTO.keyStorePath = "./src/test/resources/server.keystore";
|
||||
webServerDTO.keyStorePassword = "password";
|
||||
|
||||
WebServerComponent webServerComponent = new WebServerComponent();
|
||||
Assert.assertFalse(webServerComponent.isStarted());
|
||||
webServerComponent.configure(webServerDTO, "./src/test/resources/", "./src/test/resources/");
|
||||
webServerComponent.start();
|
||||
// Make the connection attempt.
|
||||
String keyStoreProvider = "JKS";
|
||||
|
||||
SSLContext context = SSLSupport.createContext(keyStoreProvider,
|
||||
webServerDTO.keyStorePath,
|
||||
webServerDTO.keyStorePassword,
|
||||
keyStoreProvider,
|
||||
webServerDTO.keyStorePath,
|
||||
webServerDTO.keyStorePassword);
|
||||
|
||||
SSLEngine engine = context.createSSLEngine();
|
||||
engine.setUseClientMode(true);
|
||||
engine.setWantClientAuth(true);
|
||||
final SslHandler sslHandler = new SslHandler(engine);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
final ClientHandler clientHandler = new ClientHandler(latch);
|
||||
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer() {
|
||||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline().addLast(sslHandler);
|
||||
ch.pipeline().addLast(new HttpClientCodec());
|
||||
ch.pipeline().addLast(clientHandler);
|
||||
}
|
||||
});
|
||||
Channel ch = bootstrap.connect("localhost", 8448).sync().channel();
|
||||
|
||||
URI uri = new URI(SECURE_URL);
|
||||
// Prepare the HTTP request.
|
||||
HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath());
|
||||
request.headers().set(HttpHeaders.Names.HOST, "localhost");
|
||||
|
||||
// Send the HTTP request.
|
||||
ch.writeAndFlush(request);
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
assertEquals(clientHandler.body, "12345");
|
||||
// Wait for the server to close the connection.
|
||||
ch.close();
|
||||
Assert.assertTrue(webServerComponent.isStarted());
|
||||
webServerComponent.stop();
|
||||
Assert.assertFalse(webServerComponent.isStarted());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleSecureServerWithClientAuth() throws Exception {
|
||||
WebServerDTO webServerDTO = new WebServerDTO();
|
||||
webServerDTO.bind = "https://localhost:8448";
|
||||
webServerDTO.path = "webapps";
|
||||
webServerDTO.keyStorePath = "./src/test/resources/server.keystore";
|
||||
webServerDTO.keyStorePassword = "password";
|
||||
webServerDTO.clientAuth = true;
|
||||
webServerDTO.trustStorePath = "./src/test/resources/server.keystore";
|
||||
webServerDTO.trustStorePassword = "password";
|
||||
|
||||
WebServerComponent webServerComponent = new WebServerComponent();
|
||||
Assert.assertFalse(webServerComponent.isStarted());
|
||||
webServerComponent.configure(webServerDTO, "./src/test/resources/", "./src/test/resources/");
|
||||
webServerComponent.start();
|
||||
// Make the connection attempt.
|
||||
String keyStoreProvider = "JKS";
|
||||
|
||||
SSLContext context = SSLSupport.createContext(keyStoreProvider,
|
||||
webServerDTO.keyStorePath,
|
||||
webServerDTO.keyStorePassword,
|
||||
keyStoreProvider,
|
||||
webServerDTO.trustStorePath,
|
||||
webServerDTO.trustStorePassword);
|
||||
|
||||
SSLEngine engine = context.createSSLEngine();
|
||||
engine.setUseClientMode(true);
|
||||
engine.setWantClientAuth(true);
|
||||
final SslHandler sslHandler = new SslHandler(engine);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
final ClientHandler clientHandler = new ClientHandler(latch);
|
||||
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer() {
|
||||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline().addLast(sslHandler);
|
||||
ch.pipeline().addLast(new HttpClientCodec());
|
||||
ch.pipeline().addLast(clientHandler);
|
||||
}
|
||||
});
|
||||
Channel ch = bootstrap.connect("localhost", 8448).sync().channel();
|
||||
|
||||
URI uri = new URI(SECURE_URL);
|
||||
// Prepare the HTTP request.
|
||||
HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath());
|
||||
request.headers().set(HttpHeaders.Names.HOST, "localhost");
|
||||
|
||||
// Send the HTTP request.
|
||||
ch.writeAndFlush(request);
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
assertEquals(clientHandler.body, "12345");
|
||||
// Wait for the server to close the connection.
|
||||
ch.close();
|
||||
Assert.assertTrue(webServerComponent.isStarted());
|
||||
webServerComponent.stop();
|
||||
Assert.assertFalse(webServerComponent.isStarted());
|
||||
}
|
||||
|
||||
class ClientHandler extends SimpleChannelInboundHandler<HttpObject> {
|
||||
|
||||
private CountDownLatch latch;
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue