SslConnector.java interface has been changed in the newest Jetty 7.3.1.v20110307.
Almost all off the methods have been marked as deprecated without mentioning the replacement interface or methods to use.
I've checked the jetty-users and jetty-dev mailing lists for the information with no luck.
Is there anybody out there who knows how should be the code changed for the future?
Thanks in advance!
Okay, digging out from the subversion changelog for the corresponding commits (crazy) it came out that SslContextFactory should be used.
Example:
final SslContextFactory sslContextFactory = new SslContextFactory(sKeyStore);
sslContextFactory.setKeyStorePassword(sPassword);
final SslSocketConnector conn = new SslSocketConnector(sslContextFactory);
conn.setReuseAddress(true);
// ...
Building on your own answer:
Server server = new Server();
// Encrypt the connection using a valid certificate/keystore
SslContextFactory sslContextFactory = new SslContextFactory("path/keystore.jks");
sslContextFactory.setKeyStorePassword("password");
// Create a new SocketConnector at port 443, which is the default port for
// HTTPS web pages (no port number needs to be specified in the browser).
SslSocketConnector sslConnector = new SslSocketConnector(sslContextFactory);
sslConnector.setPort(443);
// Add the SocketConnector to the server
server.setConnectors(new Connector[] {sslConnector});
Related
I'm trying to use firebase to authenticate my users via Google. On my Java server I'm verifying the validity of the idToken and every time I get this error:
com.google.firebase.auth.FirebaseAuthException: Error while verifying token signature.
I identified the problem as being the proxy of my server that avoid the http requests made by the sdk. I tested my code on my computer and it works so I'm pretty sure the problem is the proxy.
Here is my code:
InputStream serviceAccount = getClass().getClassLoader().getResourceAsStream(<fileName>);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(<address>, <port>));
HttpTransport httpTransport = new NetHttpTransport.Builder().setProxy(proxy).build();
HttpTransportFactory httpTransportFactory = () -> httpTransport;
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount, httpTransportFactory))
.setDatabaseUrl(<adress>)
.setHttpTransport(httpTransport)
.build();
FirebaseApp.initializeApp(options);
FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdTokenAsync(<token>).get();
What am I doing wrong ?
I believe this is a bug. As you can see here, the token verifier does not use the HTTP transport injected through options. I'd appreciate if you can create an issue for this on GitHub.
In the meantime, you might be able to get around this limitation by configuring the HTTP/S proxy for the JVM. Try setting the https.proxyHost and https.proxyPort system properties when starting the JVM (more details here).
I've faced the same problem, and still waiting for a greater solution.
In the meantime, I've decompiled the WebSocket class (com.google.firebase.database.tubesock.WebSocket), and created an underlying socket by myself, then droped this decompiled class in a new package in my project: com.google.firebase.database.tubesock.
The creation of the SSLSocket is around the line 295 of this class.
I've created the socket this way:
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
InetSocketAddress proxyAddr = new InetSocketAddress("200.5.92.169", 8080);
Socket underlying = new Socket(new Proxy(Proxy.Type.HTTP, proxyAddr));
underlying.connect(new InetSocketAddress(host, port));
SSLSocket sslSocket = (SSLSocket) factory.createSocket(underlying, host, port, true);
I have successfully created an embedded HttpServer using the example at https://hc.apache.org.httpcomponents-core-ga/httpcore/examples/org/apache/http/examples/HttpFileServer.java, which handles http: traffic just fine. Now I would like to extend this to support TLS.
I copied some likely looking code from here: https://hc.apache.org/httpcomponents-core-ga/tutorial/html/blocking-io.html#d5e455
But some parts of it are showing up as deprecated, which makes me wonder whether this example is out of date and whether the tree I'm at is the one where I should be barking. Even if that weren't the case, I am having trouble finding the relationship between HttpServer and DefaultBHttpClientConnection (mentioned in the example). I suspect that I should be using DefaultBHttpServerConnection but I am so far unable to find that either.
Is there a newer example of this anywhere?
Michael D. Spence
Mockingbird Data Systems, Inc.
I am not sure understand the problem you are having. All you need is to provide a correctly initialized SSLContext instance to ServerBoostrap . HttpCore ships with SSLContextBuilder specifically designed to simplify the process of SSLContext initialization.
The example included in HttpCore distribution pretty much shows every step required to set up SSL/TLS transport layer.
SSLContext sslcontext = null;
if (port == 8443) {
// Initialize SSL context
URL url = HttpFileServer.class.getResource("/my.keystore");
if (url == null) {
System.out.println("Keystore not found");
System.exit(1);
}
sslcontext = SSLContexts.custom()
.loadKeyMaterial(url, "secret".toCharArray(), "secret".toCharArray())
.build();
}
SocketConfig socketConfig = SocketConfig.custom()
.setSoTimeout(15000)
.setTcpNoDelay(true)
.build();
final HttpServer server = ServerBootstrap.bootstrap()
.setListenerPort(port)
.setServerInfo("Test/1.1")
.setSocketConfig(socketConfig)
.setSslContext(sslcontext)
.setExceptionLogger(new StdErrorExceptionLogger())
.registerHandler("*", new HttpFileHandler(docRoot))
.create();
server.start();
I'm migrating a web application with embedded Jetty from 7 to 9.3.2 and as such am in need of updating the code a little. The application itself has a multitude of connectors written for it, for web UI, API endpoint and also for authenticating to the web interface via a smart card. The connector method for achieving that is implemented as follows (for Jetty 7).
private Connector createSmartCardConnector() {
SslContextFactory sslContextFactory = createSslContextFactory(smartCardUiKeyStoreFile);
LOG.info("Using truststore file: " + trustStoreFile);
sslContextFactory.setTrustStore(trustStoreFile);
sslContextFactory.setTrustStorePassword("password");
sslContextFactory.setNeedClientAuth(true);
Connector connector = new SslSocketConnector(sslContextFactory) {
#Override public void accept(int acceptorID) throws IOException, InterruptedException {
Socket socket = _serverSocket.accept();
configure(socket);
SslConnectorEndPoint connection = new SslConnectorEndPoint(socket);
SMART_CARD_SOCKETS.add((SSLSocket) socket);
connection.dispatch();
}
};
As is apparent from the code, the SslSocketConnector.accept() method is overridden and the only part that is added is SMART_CARD_SOCKETS.add((SSLSocket) socket);. SMART_CARD_SOCKETS is a set that is later used for destroying the objects (sockets) being added to it. My question here is how to achieve the same functionality in Jetty 9, the point of which is that when the smart card is removed from the user's computer, the socket would be destroyed when the user attempts to navigate further.
I have tried to override the ServerConnector.accept() method in Jetty 9, however it uses a private method in it, which makes this impossible.
What you want is a custom implementation of HttpConfiguration.Customizer.
Add it to your HttpConfiguration for the ServerConnector you are interested in, and then it will run with each accept.
Example use of SecureRequestCustomizer.java.
// Setup SSL
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("/path/to/keystore");
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setKeyManagerPassword("password");
// Setup HTTPS Configuration
HttpConfiguration httpsConf = new HttpConfiguration();
httpsConf.setSecurePort(8443);
httpsConf.setSecureScheme("https");
httpsConf.addCustomizer(new SecureRequestCustomizer()); // adds ssl info to request
// Establish the ServerConnector
ServerConnector httpsConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory,"http/1.1"),
new HttpConnectionFactory(httpsConf));
httpsConnector.setPort(httpsPort);
server.addConnector(httpsConnector);
I'm implementing a servlet in an embedded Jetty (9.3.0.v20150612) and I would like to use HTTP/2.
I'm enabling ALPN for protocol negotiation to select either HTTP1.1 or HTTP2.
When I'm sending an HTTPs request to my servlet from Safari 8 (supports only HTTP1.1) or Safari 9 (support both HTTP1.1 & HTTP2) I get an answer from my servlet.
When I execute the same request from Firefox 39, it doesn't work and I just get NS_ERROR_ABORT. I have the same issue with Chrome.
I have two questions:
Why I don't get answer from Chrome & Firefox
How can I know if with Safari 9, HTTP/2 has been used instead of HTTP1.1? (My IOS9 App is also connecting without issue)
Below is the code to perform the initialization of Jetty
private void startHTTP2Server() {
WebServerProperties webProperties = WebServerProperties.getInstance();
HttpConfiguration config = getHttpConfiguration();
HttpConnectionFactory http1 = new HttpConnectionFactory(config);
HTTP2ServerConnectionFactory http2 = new HTTP2ServerConnectionFactory(config);
NegotiatingServerConnectionFactory.checkProtocolNegotiationAvailable();
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
alpn.setDefaultProtocol(http1.getProtocol()); // sets default protocol to HTTP 1.1
// SSL Connection Factory
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(webProperties.getKeystore());
sslContextFactory.setKeyStorePassword(webProperties.getKeystorePassword());
//sslContextFactory.setKeyManagerPassword(KEYSTORE_PW);
//sslContextFactory.addExcludeCipherSuites(".*RC4.*");
//sslContextFactory.addExcludeCipherSuites("TLS_DHE_RSA.*");
sslContextFactory.setProtocol(webProperties.getTLSVersion()); // SEB
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
Server server = new Server();
//ServerConnector connector = new ServerConnector(server, ssl, alpn, http2, http1);
ServerConnector connector = new ServerConnector(server, ssl, alpn, http2, http1);
connector.setPort(webProperties.getPort());
server.addConnector(connector);
// --- SEB
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath(webProperties.getServletContext());
context.setResourceBase(System.getProperty(webProperties.getServletTmpDir()));
server.setHandler(context);
// Add dump servlet
context.addServlet(IMonServer.class, webProperties.getServletPath());
try {
server.start();
server.join();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static HttpConfiguration getHttpConfiguration() {
WebServerProperties webProperties = WebServerProperties.getInstance();
HttpConfiguration config = new HttpConfiguration();
config.setSecureScheme("https");
config.setSecurePort(webProperties.getPort());
config.setSendXPoweredBy(true);
config.setSendServerVersion(true);
config.addCustomizer(new SecureRequestCustomizer());
return config;
}
When I'm starting the server, I give also the Java option -Xbootclasspath/p:$installDirectory/lib/alpn-boot-8.1.3.v20150130.jar
Is there anything wrong or missing?
Thanks for your help,
Regards,
Your code is correct, it just lacks two more lines that are important to get HTTP/2 to work correctly.
When you configure the SslContextFactory, add the lines:
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
sslContextFactory.setUseCipherSuitesOrder(true);
What these two lines do is to sort the TLS ciphers to prefer the HTTP/2 ones before the others, and to ask to respect that order.
Without sorting, the server was falling back to an older draft version of HTTP/2 (h2-14) that did not enforce cipher strength, but this is unfortunately rejected by Chrome and Firefox.
I don't know exactly why it is working with Safari: either a Safari bug, or a more relaxed interpretation of the HTTP/2 specification with regard to cipher strength with respect to other browsers.
Hi do any one having idea about setting setEnabledProtocols other than java code
SSLSocket.setEnabledProtocols(newProtocol);
Because in our web service code we couldn't find any socket connection.
Thanks in advance. Appreciate your help if you guide me in setting dynamic UNIX java command.
Like that:
SSLContext context = SSLUtils.createSSLContext();
// Connect to the tracer
SSLSocketFactory factory = context.getSocketFactory();
SSLSocket sslSocket = (SSLSocket)factory.createSocket(endpointId.getHostName(),
endpointId.getPort());
// Enable TLS protocols
SSLParameters params = new SSLParameters();
params.setProtocols(new String[] {"TLSv1", "TLSv1.1","TLSv1.2"});
sslSocket.setSSLParameters(params);
// Initialize the SSL handshake
sslSocket.startHandshake();
I have used System.setproperty("https.protocol","SSLv3"); and now its working fine.