CometD: Use SSL/TLS - java

How do I enable secure connections with CometD?
I have an app that is working when I use an "http" protocol for the BayeuxServer. If I switch to "https", I get failed handshakes.
What is the correct way to use a secure connection in CometD?
This is via the Java Client.
Here is the error:
{failure={exception=java.lang.NullPointerException, message={ext={ack=true}, supportedConnectionTypes=[long-polling], channel=/meta/handshake, id=4, version=1.0}, connectionType=long-polling}, channel=/meta/handshake, id=4, subscription=null, successful=false}
I do not see any exceptions on the server (ie, the null pointer is not in our code), and if I use HTTP, it works fine.
I've pieced together the following for the Java client side:
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setTrustAll(true); // only interacting with our backend, so accept self-signed certs
WebSocketClient webSocketClient = new WebSocketClient(sslContextFactory);
webSocketClient.start();
ClientTransport wsTransport = new JettyWebSocketTransport(null, null, webSocketClient);
HttpClient httpClient = new HttpClient(sslContextFactory);
httpClient.start();
ClientTransport httpTransport = new LongPollingTransport(null, httpClient);
I believe that will do it.
I still need to figure out how to configure the server side cometd to accept the secure connections. I am using the Spring setup.
The answer to the server side is: Its a pain in the ass.
Here is how you can get it working with the jetty maven plugin:
http://juplo.de/configure-https-for-jetty-maven-plugin-9-0-x/#comment-53352

Related

need to send APNS push with http/2 java

Any help : I am using legacy code to send APNs push notification to iOS device. Now, the issue is sometimes push gets delayed and some times it is missed. So want to switch to http/2 which Apple supports now. I used jetty but it is not working fine. Any help or reference would be appreciable.
My code is below:
public void sendHttp2Push(){
String badgeCount ="1";
HTTP2Client http2Client = new HTTP2Client();
http2Client.start();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("abcDistribution.p12"), "abc123".toCharArray());
SslContextFactory ssl = new SslContextFactory(true);
ssl.setKeyStore(ks);
ssl.setKeyStorePassword("abc123");
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), ssl);
client.start();
Request req = client.POST("https://api.push.apple.com:2195")
.path("/3/device/c9addc2f2ec6cdb9baafb5232bbc0f5d0e877ca1076619476d27c6a1ce5871c9")
ContentResponse response = req.send();
}
I am using the above mentioned code to send push notification with http/2 using jetty client.
The first step in sending a remote notification is to establish a connection with the appropriate APNs server:
Development server: api.development.push.apple.com:443
Production server: api.push.apple.com:443

Ignore certificate validation - Tomcat8 WebSocket (JSR-356)

SslContextFactory sec = new SslContextFactory();
sec.setValidateCerts(false);
WebSocketClient client = new WebSocketClient(sec);
The above code is implemented for Jetty WebSockets, to tell the java client to disable certificate validation. Is there any way I can achieve the same in Java API for Tomcat8 WebSockets (JSR-356)?
PS: I have tried this method. It didn't work for Secure WebSocket connection of Tomcat WebSockets
Did you generate self signed certificate and trying to use it?
Then import your self signed certificate to new keystore and use that keystore as a trust store on your client side.
For a tyrus websocket client, I use like this:
String keyStorePath = StompClientTest.class.getResource("/myapp.keystore").getPath();
System.getProperties().put("javax.net.debug", "all"); // debug your certificate checking
System.getProperties().put(SslContextConfigurator.KEY_STORE_FILE, keyStorePath);
System.getProperties().put(SslContextConfigurator.TRUST_STORE_FILE, keyStorePath);
System.getProperties().put(SslContextConfigurator.KEY_STORE_PASSWORD, "secret");
System.getProperties().put(SslContextConfigurator.TRUST_STORE_PASSWORD, "secret");
final SslContextConfigurator defaultConfig = new SslContextConfigurator();
defaultConfig.retrieve(System.getProperties());
SslEngineConfigurator sslEngineConfigurator = new SslEngineConfigurator(defaultConfig);
sslEngineConfigurator.setHostVerificationEnabled(false);
StandardWebSocketClient webSocketClient = new StandardWebSocketClient();
webSocketClient.getUserProperties().put(ClientProperties.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator);
For tomcat read answer in following question: https://stackoverflow.com/a/32205864/386213

Validating client credentials on a server using Java SimpleFramework

I am developing a SSL/TLS enabled server using the Java SimpleFramework. I am wondering how to validate client authentications on the server.
On the server side, I am extending org.simpleframework.http.core.ContainerServer and overriding the process() method as follows:
#Override
public void process(Socket socket) throws IOException {
// Ensures client authentication is required
socket.getEngine().setNeedClientAuth(true);
super.process(socket);
}
This is to make sure that clients authenticate. Note that if I remove the call to setNeedClientAuth(), my program works perfectly.
On the client side, the following code is used:
HttpClient client = new HttpClient();
Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");
client.getState().setCredentials(AuthScope.ANY, defaultcreds);
GetMethod get = new GetMethod("https://url.to.server");
get.setDoAuthentication(true);
client.executeMethod(get);
When enabling authentication requirement, I get the following exception:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
I am guessing this relates to the fact that the passed credentials is never validated.
To summarize my question, how should I proceed to validate clients on the server?

How to work with client certificates on Jetty SPDY with ALPN?

I have problem with client certifiacates when I use SPDY with Jetty.
It works when I work with NPN and start Jetty SPDY server with:
SSLconnector = new HTTPSPDYServerConnector(server, sslContextFactory);
As a baseRequest.getHttpChannel() it uses org.eclipse.jetty.spdy.server.http.HttpChannelOverSPDY and I can read SSL properties like SSL_SESSION_ID and client certificates with code like:
// ... HttpServletRequest request
java.security.cert.X509Certificate client_certs[] = (java.security.cert.X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
But NPN is not an option in Java8 (see my question How to run Jetty with SPDY using ALPN?). In Java8 I have to use ALPN protocol like:
sslContextFactory.setWantClientAuth(w3srv_config.want_client_auth);
// ...
HttpConfiguration httpConfig = new HttpConfiguration();
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, "alpn");
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory("spdy/3", "http/1.1");
alpn.setDefaultProtocol("http/1.1");
HTTPSPDYServerConnectionFactory spdy = new HTTPSPDYServerConnectionFactory(SPDY.V3, httpConfig);
HttpConnectionFactory http = new HttpConnectionFactory(httpConfig);
SSLconnector = new ServerConnector(server, new ConnectionFactory[]{ssl, alpn, spdy, http});
//...
With this code I got null when I want to get any SSL related javax.servlet.request.*. Its baseRequest.getHttpChannel() is org.eclipse.jetty.server.HttpConnection$HttpChannelOverHttp.
What I have to change to work with client certificates?
The javax.servlet.request.* properties you are looking for are set by Jetty's SecureRequestCustomizer, which you need to add to the httpConfig object you create in your code example above.
I am guessing that your NPN configuration is slightly different, or you use some utility method in Jetty that does this for you with NPN but not with ALPN.
Just doing:
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new SecureRequestCustomizer());
should be enough to fix your issue.

Apache HTTP Client socks proxy

I am currently working at a web requests project and I am using Apache Http Client library. I try to connect to a server (E.g. http://www.google.com) with an working Socks v4/5 tested with mozilla firefox but the problem is that I never get a response. Only different errors...
Here is a code snippet:
//HttpClient
DefaultHttpClient http = new DefaultHttpClient();
//A class defined by me
Proxy proxy = bla bla;
HttpHost host = new HttpHost(proxy.getIP(), proxy.getPort());
if (proxy.getUsername() != null) {
http.getCredentialsProvider().setCredentials(
new AuthScope(proxy.getIP(), proxy.getPort()),
new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword()));
}
http.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, host);
Can anyone tell a proper way to initiate comunnication through SOCKS proxies? Thanks!
Note: The code above works perfect with HTTP proxies.
Http proxy and socks proxy has very different protocols ( http://en.wikipedia.org/wiki/SOCKS#Comparison ).
For your question:
You can do thTis by native java socket ( How can I configure HTTPClient to authenticate against a SOCKS proxy? ) or create your own implementation over DefaultClientConnectionOperator, here is good guide ( http://4devops.blogspot.com/2011/10/httphttps-over-socks-proxy-with-java.html )

Categories

Resources