All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.fabric8.utils.cxf.WebClients Maven / Gradle / Ivy

There is a newer version: 3.0.12
Show newest version
/**
 *  Copyright 2005-2016 Red Hat, Inc.
 *
 *  Red Hat licenses this file to you under the Apache License, version
 *  2.0 (the "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 *  implied.  See the License for the specific language governing
 *  permissions and limitations under the License.
 */
package io.fabric8.utils.cxf;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.ws.rs.WebApplicationException;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.cfg.Annotations;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import io.fabric8.utils.Strings;
import io.fabric8.utils.ssl.TrustEverythingSSLTrustManager;
import net.oauth.signature.pem.PEMReader;
import net.oauth.signature.pem.PKCS1EncodedKeySpec;
import org.apache.cxf.attachment.Base64DecoderStream;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.auth.DigestAuthSupplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static io.fabric8.utils.cxf.JsonHelper.createObjectMapper;

/**
 */
public class WebClients {
    private static final transient Logger LOG = LoggerFactory.getLogger(WebClients.class);

    public static InputStream getInputStreamFromDataOrFile(String data, File file) throws FileNotFoundException {
        if (data != null) {
            return new Base64DecoderStream(new ByteArrayInputStream(data.getBytes()));
        }
        if (file != null) {
            return new FileInputStream(file);
        }
        return null;
    }

    public static KeyStore createTrustStore(String caCertData, File caCertFile) throws Exception {
        try (InputStream pemInputStream = getInputStreamFromDataOrFile(caCertData, caCertFile)) {
            CertificateFactory certFactory = CertificateFactory.getInstance("X509");
            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(pemInputStream);

            KeyStore trustStore = KeyStore.getInstance("JKS");
            trustStore.load(null);

            String alias = cert.getSubjectX500Principal().getName();
            trustStore.setCertificateEntry(alias, cert);

            return trustStore;
        }
    }

    public static void configureCaCert(WebClient webClient, String caCertData, File caCertFile) {
        try {
            KeyStore trustStore = createTrustStore(caCertData, caCertFile);
            TrustManagerFactory trustManagerFactory =
                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

            HTTPConduit conduit = WebClient.getConfig(webClient)
                    .getHttpConduit();

            TLSClientParameters params = conduit.getTlsClientParameters();

            if (params == null) {
                params = new TLSClientParameters();
                conduit.setTlsClientParameters(params);
            }

            TrustManager[] existingTrustManagers = params.getTrustManagers();

            if (existingTrustManagers != null && existingTrustManagers.length > 0) {
                List list = new ArrayList<>();
                list.addAll(Arrays.asList(existingTrustManagers));
                list.addAll(Arrays.asList(trustManagers));
                trustManagers = list.toArray(new TrustManager[list.size()]);
            }

            params.setTrustManagers(trustManagers);
        } catch (Exception e) {
            LOG.error("Could not create trust manager for " + caCertFile, e);
        }
    }

    public static void disableSslChecks(WebClient webClient) {
        HTTPConduit conduit = WebClient.getConfig(webClient)
                .getHttpConduit();

        TLSClientParameters params = conduit.getTlsClientParameters();

        if (params == null) {
            params = new TLSClientParameters();
            conduit.setTlsClientParameters(params);
        }

        params.setTrustManagers(new TrustManager[]{new TrustEverythingSSLTrustManager()});

        params.setDisableCNCheck(true);
    }

    public static void disableHostNameChecks(WebClient webClient) {
        HTTPConduit conduit = WebClient.getConfig(webClient)
                .getHttpConduit();

        TLSClientParameters params = conduit.getTlsClientParameters();

        if (params == null) {
            params = new TLSClientParameters();
            conduit.setTlsClientParameters(params);
        }
        LOG.debug("Disabling host name checks");

        params.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        });
    }

    public static void configureClientCert(WebClient webClient, String clientCertData, File clientCertFile, String clientKeyData, File clientKeyFile, String clientKeyAlgo, char[] clientKeyPassword) {
        try {
            KeyStore keyStore = createKeyStore(clientCertData, clientCertFile, clientKeyData, clientKeyFile, clientKeyAlgo, clientKeyPassword);
            KeyManagerFactory keyManagerFactory =
                    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, clientKeyPassword);
            KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();

            HTTPConduit conduit = WebClient.getConfig(webClient)
                    .getHttpConduit();

            TLSClientParameters params = conduit.getTlsClientParameters();

            if (params == null) {
                params = new TLSClientParameters();
                conduit.setTlsClientParameters(params);
            }

            KeyManager[] existingKeyManagers = params.getKeyManagers();

            if (existingKeyManagers != null && existingKeyManagers.length > 0) {
                List list = new ArrayList<>();
                list.addAll(Arrays.asList(existingKeyManagers));
                list.addAll(Arrays.asList(keyManagers));
                keyManagers = list.toArray(new KeyManager[list.size()]);
            }

            params.setKeyManagers(keyManagers);

        } catch (Exception e) {
            LOG.error("Could not create key manager for " + clientCertFile + " (" + clientKeyFile + ")", e);
        }
    }

    public static KeyStore createKeyStore(String clientCertData, File clientCertFile, String clientKeyData, File clientKeyFile, String clientKeyAlgo, char[] clientKeyPassword) throws Exception {
        try (InputStream certInputStream = getInputStreamFromDataOrFile(clientCertData, clientCertFile)) {
            CertificateFactory certFactory = CertificateFactory.getInstance("X509");
            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certInputStream);

            InputStream keyInputStream = getInputStreamFromDataOrFile(clientKeyData, clientKeyFile);
            PEMReader reader = new PEMReader(keyInputStream);
            RSAPrivateCrtKeySpec keySpec = new PKCS1EncodedKeySpec(reader.getDerBytes()).getKeySpec();
            KeyFactory kf = KeyFactory.getInstance(clientKeyAlgo);
            RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(keySpec);

            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(null, clientKeyPassword);

            String alias = cert.getSubjectX500Principal().getName();
            keyStore.setKeyEntry(alias, privKey, clientKeyPassword, new Certificate[] {cert});

            return keyStore;
        }
    }

    public static void configureUserAndPassword(WebClient webClient, String username, String password) {
        if (Strings.isNotBlank(username) && Strings.isNotBlank(password)) {
            HTTPConduit conduit = WebClient.getConfig(webClient).getHttpConduit();
            conduit.getAuthorization().setUserName(username);
            conduit.getAuthorization().setPassword(password);
        }
    }
    
    public static void enableDigestAuthenticaionType(WebClient webClient) {
        HTTPConduit conduit = WebClient.getConfig(webClient).getHttpConduit();
        conduit.setAuthSupplier(new DigestAuthSupplier());
    }

    public static List createProviders() {
        List providers = new ArrayList();
        Annotations[] annotationsToUse = JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS;
        ObjectMapper objectMapper = createObjectMapper();
        providers.add(new JacksonJaxbJsonProvider(objectMapper, annotationsToUse));
        providers.add(new ExceptionResponseMapper());
        return providers;
    }



    /**
     * A helper method to handle REST APIs which throw a 404 by just returning null
     */
    public static  T handle404ByReturningNull(Callable callable) {
        try {
            return callable.call();
        } catch (WebApplicationException e) {
            if (e.getResponse().getStatus() == 404) {
                return null;
            } else {
                throw e;
            }
        } catch (Exception e) {
            throw new WebApplicationException(e);
        }
    }
}