pinkpanther
pinkpanther

Reputation: 4808

How to configure wildfly to use https with ClientBuilder in resteasy?

This is the first time ever I got the requirement to connect to https url. Within no time, I came to know that I need SSLContext to be passed.

I also came to know that I need to configure in standalone.xml to get it done.

Any pointers towards the solution/link, working code would be much appreciated.

Do we have to generate keystores ourselves? or wildfly provides any existing ones?

This is what I've tried:

    SSLContext context = null;
    KeyManagerFactory kmf = null;
    KeyStore ks = null;
    char[] storepass = "somestringhere".toCharArray();
    char[] keypass = "somestringhere".toCharArray();

    try {
        context = SSLContext.getInstance("SSL");
    } catch (NoSuchAlgorithmException e3) {
        // TODO Auto-generated catch block
        e3.printStackTrace();
    }
    try {
        kmf = KeyManagerFactory.getInstance("SunX509");
    } catch (NoSuchAlgorithmException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    FileInputStream fin = null;
    try {
        fin = new FileInputStream("file here");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        ks = KeyStore.getInstance("JKS");
    } catch (KeyStoreException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        ks.load(fin, storepass);
    } catch (NoSuchAlgorithmException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (CertificateException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    try {
        kmf.init(ks, keypass);
    } catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        context.init(kmf.getKeyManagers(), null, null);
    } catch (KeyManagementException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Client client = ClientBuilder.newBuilder().sslContext(context).build();

    WebTarget target = client
            .target("https://....");

    Builder builder = target.request();

I tried https://stackoverflow.com, it gave 200OK, I tried google.com, it said document has moved 302 status. I tried the url which I want to connect I got peer not authenticated exception

Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:421) [jsse.jar:1.7.0_71]
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) [httpclient-4.2.5.jar:4.2.5]
    at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283) [resteasy-client-3.0.6.Final.jar:]
    ... 30 more

And the server asks for basic authentication, is it the reason for the exception?

Upvotes: 4

Views: 6360

Answers (2)

AIMABLE
AIMABLE

Reputation: 1085

Here are my codes to use JAX-RS with HTTPS using Wildly 10.Note that Wildly implementation for JAX-RS is RestEasy 3.xxxx.

ClientBuilder builder = ClientBuilder.newBuilder();
builder.sslContext(ConnectionFactory.getSslContext());
builder.hostnameVerifier(ConnectionFactory.getHostnameVerifier());
client = builder.build();
String baseURI = acsUser.getSelectedService().getWebserviceBaseUrl();
WebTarget webTarget = client.target(baseURI);

Here is the class called ConnectionFactory.

public class ConnectionFactory {

Proxy proxy;

String proxyHost;

Integer proxyPort;

public boolean canConnect = true;

private static final Logger log = Logger.getLogger("ReportPortal");

public ConnectionFactory() {
}

/**
 *
 * @return
 */
public static SSLContext getSslContext() {
    SSLContext sslContext = null;
    try {
        sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new TrustManager[]{new      SecureTrustManager()}, new SecureRandom());
    }
    catch (NoSuchAlgorithmException | KeyManagementException ex) {
        log.error("ERROR OCCURS", ex);
    }
    return sslContext;
}

/**
 *
 * @return
 */
public static HostnameVerifier getHostnameVerifier() {
    return (String hostname, javax.net.ssl.SSLSession sslSession) -> true;
}

public Boolean isHttps(String url) {

    if (url.startsWith("https://")) {
        return Boolean.TRUE;
    }
    else {
        return Boolean.FALSE;
    }
}

}

Upvotes: 4

Paul Samsotha
Paul Samsotha

Reputation: 209082

"Do we have to generate keystores ourselves?"

Yes. You need to generate one for the Server and a Trust store (which is just a key store, but we just call it a trust store to differentiate it).

See SSL setup guide in the Wildfly documentation. It will show you how to create a keystore and configure it with Wildfly. Just follow the section "Pure Java SSL-Setup using keytool"

Then you need to create the client keystore. You will export the certificate from the server store and import it into the client store.

How it works is that the Client needs to trust the server. And the way to do that is through the Server certificate. Now if the certificate is signed by from a well known CA, generally Java will already support this cert, and we dont need to configure the client. But since you are creating your own self signed cert, we need to configure the client to trust the server certificate by importing it into the trust-store.

You can see all the step for handling the certs/stores for both client and server here in this post. Scroll down to step 5. The three code snippets that begin with keytool are the commands to complete this task. The first creates the server store named tomcat-keystore.jks (but you can name it anything). The next snippet exports the certificate from the keystore, into a file name tomcat.crt (but you an name it anything). The third command will import the previous cert into a client-truststore.jks (but you can name it anything). You'll notice that you don't need to explicitly create the trust-store, it be will create implicitly when we do an import.

Once you have the server keystore, follow the instructions in the wildfly documentation linked above and configure the store with the server.

To configure the Client, see step 6 in the above linked answer. It configures the client with the trust-store we created. Everything in the code is standard Java and JAX-RS except for the configuration of the Basic auth, which is specific to Jersey.

Upvotes: 3

Related Questions